Comment devez-vous organiser vos chaises?

20

Vous enseignez à une classe d'élèves ayant des préférences intéressantes quant à la disposition de leurs chaises. Il y a 3 exigences très spécifiques pour la disposition des chaises:

  1. La plupart sont disposées dans un rectangle, même si cela signifie que certaines chaises sont vides.

  2. Il doit y avoir aussi peu de chaises vides que possible.

  3. Ils doivent être aussi "carrés" que possible. La carréité est déterminée par la distance entre la largeur et la hauteur du rectangle, plus c'est bas, mieux c'est. Par exemple, un rectangle qui 4x7a un carré de 3.

Pour être plus précis, le «score» d'un arrangement est la distance entre la largeur et la hauteur plus le nombre de chaises qui se videraient.

Prenons un exemple. Disons que vous avez 13 étudiants. Vous pouvez organiser les chaises de l'une des manières suivantes:

1x13
2x7
3x5
4x4

1x13n'est pas très carré. En fait, 1 et 13 sont séparés de 12, nous donnons donc à cet arrangement 12 points. Il a également 0 chaises vides, nous ajoutons donc 0 points, ce qui donne à cet arrangement un score de 12. Pas terrible.

2x7c'est certainement mieux. 2 et 7 ne sont séparés que par 5, nous accordons donc 5 points à cet arrangement. Cependant, si vous disposiez réellement 2 rangées de sept chaises, cela prendrait 14 chaises, ce qui signifie qu'une chaise serait vide. Nous ajoutons donc un point, donnant à cet arrangement un score de 6.

On pourrait aussi faire 3x5. 3 et 5 sont à 2, donc +2 points. Cela prend 15 chaises, ce qui signifie que nous aurions deux chaises supplémentaires, donc encore +2 points, pour un score de 4.

La dernière option, 4x4. 4 et 4 sont 0 à part, donc nous donnons ce +0 points. 4x4 prend 16 chaises, donc 3 chaises sont vides, pour un score total de 3. C'est la solution optimale.

En cas d'égalité, la solution optimale est celle avec moins de chaises vides.

Le défi

Vous devez écrire un programme ou une fonction qui prend un nombre entier et génère la disposition optimale des chaises pour ce nombre d'élèves. IO peut être dans n'importe quel format raisonnable. Voici un exemple de sortie pour n'importe quel nombre d'élèves de 1 à 100:

1:  (1, 1)
2:  (1, 2)
3:  (2, 2)
4:  (2, 2)
5:  (2, 3)
6:  (2, 3)
7:  (3, 3)
8:  (3, 3)
9:  (3, 3)
10: (2, 5)
11: (3, 4)
12: (3, 4)
13: (4, 4)
14: (4, 4)
15: (4, 4)
16: (4, 4)
17: (3, 6)
18: (3, 6)
19: (4, 5)
20: (4, 5)
21: (3, 7)
22: (5, 5)
23: (5, 5)
24: (5, 5)
25: (5, 5)
26: (4, 7)
27: (4, 7)
28: (4, 7)
29: (5, 6)
30: (5, 6)
31: (4, 8)
32: (4, 8)
33: (6, 6)
34: (6, 6)
35: (6, 6)
36: (6, 6)
37: (5, 8)
38: (5, 8)
39: (5, 8)
40: (5, 8)
41: (6, 7)
42: (6, 7)
43: (5, 9)
44: (5, 9)
45: (5, 9)
46: (7, 7)
47: (7, 7)
48: (7, 7)
49: (7, 7)
50: (5, 10)
51: (6, 9)
52: (6, 9)
53: (6, 9)
54: (6, 9)
55: (7, 8)
56: (7, 8)
57: (6, 10)
58: (6, 10)
59: (6, 10)
60: (6, 10)
61: (8, 8)
62: (8, 8)
63: (8, 8)
64: (8, 8)
65: (6, 11)
66: (6, 11)
67: (7, 10)
68: (7, 10)
69: (7, 10)
70: (7, 10)
71: (8, 9)
72: (8, 9)
73: (7, 11)
74: (7, 11)
75: (7, 11)
76: (7, 11)
77: (7, 11)
78: (9, 9)
79: (9, 9)
80: (9, 9)
81: (9, 9)
82: (7, 12)
83: (7, 12)
84: (7, 12)
85: (8, 11)
86: (8, 11)
87: (8, 11)
88: (8, 11)
89: (9, 10)
90: (9, 10)
91: (7, 13)
92: (8, 12)
93: (8, 12)
94: (8, 12)
95: (8, 12)
96: (8, 12)
97: (10, 10)
98: (10, 10)
99: (10, 10)
100: (10, 10)

Comme d'habitude, il s'agit de code-golf, donc les échappatoires standard s'appliquent, et le gagnant est la réponse la plus courte en octets.

DJMcMayhem
la source
En relation.
Martin Ender

Réponses:

8

Gelée , 16 15 14 octets

÷RĊ,Rµạ/+PỤḢịZ

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça fonctionne

÷RĊ,Rµạ/+PỤḢịZ  Main link. Argument: n

 R              Range; yield [1, ..., n].
÷               Divide n by each k in [1, ..., n].
  Ċ             Ceil; round the quotients up to the nearest integer.
    R           Range; yield [1, ..., n].
   ,            Pair; yield A := [[ ⌈n ÷ 1⌉, ..., ⌈n ÷ n⌉ ], [ 1, ..., n ]].
     µ          Begin a new, monadic chain. Argument: A
      ạ/        Reduce A by absolute difference.
                This yields [ |⌈n ÷ 1⌉ - 1|, ..., |⌈n ÷ n⌉ - n| ].
         P      Product; reduce A by multiplication.
                This yields [ ⌈n ÷ 1⌉ × 1, ..., ⌈n ÷ n⌉ × n].
       +        Add the results to left and right, element by element. This yields
                [ |⌈n ÷ 1⌉ - 1| + ⌈n ÷ 1⌉ × 1, ..., |⌈n ÷ n⌉ - n| + ⌈n ÷ n⌉ × n ].
          Ụ     Grade up; sort the indices of the list of sums by their values.
           Ḣ    Head; extract the first value, which corresponds to the smallest
                sum. Grading up is stable, so this selects the first index of all
                with the smallest sum in case of a tie. In this event, the first
                index will have the highest absolute difference of all indices
                with the smallest sum, meaning that it has the lowest product and,
                therefore, the lowest number of empty chairs.
             Z  Zip; transpose A's rows and columns.
                This yields [[ ⌈n ÷ 1⌉, 1 ], ..., [ ⌈n ÷ n⌉, n ]].
            ị   Retrieve the pair at that index.
Dennis
la source
4

Python 2, 68 octets

lambda n:min((abs(~i-n/~i)+n/~i*~i,i+1,0-n/~i)for i in range(n))[1:]

Équivalent au plus «évident»:

lambda n:min([(i+1,0-n/~i)for i in range(n)],key=lambda(p,q):abs(p-q)+p*q)
Lynn
la source
Vous pouvez enregistrer trois octets en itérant sur range(-n,0), comme je le fais dans ma réponse . Suite de tests.
Dennis
3

Haskell, 65 octets

f x=snd$minimum[((a*b+a-b,a*b),(b,a))|a<-[1..x],b<-[1..a],a*b>=x]

Exemple d'utilisation: map f [1..5]-> [(1,1),(1,2),(2,2),(2,2),(2,3)].

Traverse une boucle externe ade 1à x(x -> nombre d'élèves) et une boucle interne bde 1à a. Conserve tout (b,a)a*b>=xet construit des paires ((arrangement points,seats left), (b,a))qui suivent l'ordre lexicographique dont nous avons besoin pour trouver le minimum. Remarque: aest toujours supérieur à b, nous n'avons donc pas besoin absde carré. Pas besoin de soustraire xdu score "places restantes", car seul l'ordre relatif compte. Enfin, nous supprimons la paire de scores avec snd.

nimi
la source
Pourquoi pas juste (a b + ab, (b, a))? Si vous minimisez le score, vous minimisez sûrement un b de toute façon, ou est-ce que je manque quelque chose?
justinpc
@jpcooper: a*b(nombre de places libres) est le bris d'égalité si le score principal est égal. Par exemple n=43: a) a=7, b=7, score: (49,49)b) a=9, b=5, le score: (49,45). Le score principal est égal, le bris d'égalité décide, b) gagne.
nimi
Tu as raison. J'aurais dû mieux lire la description.
justinpc
@jpcooper: attendez une minute ... si je retire le casse-cravate a*b, les chiffres (b,a)que je dois porter de toute façon agissent comme le casse-cravate et donnent les mêmes résultats pour (au moins) n=1..300. Un produit est petit si l'un des facteurs (ici b) est petit. Mais tant que je n'ai pas de preuve formelle, je ne veux pas utiliser ce fait. Voyons voir si j'en trouve un.
nimi
Bon point. Cela semble juste et ne devrait pas être trop difficile de trouver une preuve. Je commence à me demander cependant s'il pourrait y avoir une solution linéaire à ce problème.
justinpc
2

Ruby, 64 octets

->n{(1..n).map{|w|h=(n+w-1)/w;[(h-w).abs+h*w,w*h,w,h]}.min[2,3]}

Une lambada qui prend le nombre de personnes en argument et renvoie un tableau avec la largeur et la hauteur de la solution optimale.

MegaTom
la source
Pourquoi avez-vous besoin w*hcomme deuxième élément de votre tableau? Je ne pense pas que cela change particulièrement quoi que ce soit lorsque vous appelez minparce que vous minimisez le score aka le premier élément.
Value Ink
@ KevinLau-notKenny de la question:In case of a tie, the optimal solution is the one with less empty chairs
MegaTom
2

MATL , 18 octets

:Gy/Xkvtd|yp+&X<Z)

Essayez-le en ligne!

Explication

:      % Implicit input number N. Range [1 2 ... N]
G      % Push N again
y      % Duplicate second-from-top: push [1 2 ... N] again
/Xk    % Divide and round up
v      % Vertically concatenate. Gives 2×N array of rectangle sizes
td|    % Duplicate. Absolute difference of each column
y      % Duplicate second-from-top: push 2×N array again
p      % Product of each column
+      % Sum absolute differences and products
&X<    % Arg min
Z)     % Use as column index into the 2×N array. Implicitly display
Luis Mendo
la source
2

Javascript, 98 octets

Mon premier code golf, donc je poste quand même!

f=n=>{for(o=1/0,i=1;i<=n;i++)for(j=n;i*j>=n;j--)t=i*j-n+Math.abs(i-j),o>t&&(o=t,a=[i,j]);return a}

Au départ, oc'était un objet vide et j'ai vérifié s'il o.aétait vide, donc c'était un cas spécial au premier tour. Mais j'ai trouvé l'astuce 1/0 dans la réponse d'edc65 pour initialiser la variable sur Infinity.

Thiht
la source
Et je vais essayer l'astuce pour utiliser un objet pour stocker le résultat temporaire
edc65
1

Pyth, 24 22 21 octets

Edit : dans la clé de tri, je me rends compte qu'il n'est pas nécessaire de trouver le nombre de chaises vides. C'est équivalent à marquer le nombre total de chaises. Cela m'a fait gagner 2 octets.

h.m_+B*FbaFbm,d.EcQdS

Essayez-le en ligne!

Leaky Nun
la source
1

Matlab(174) (146)121

  function g(n),f=@(n,i)ceil(n/i);x=[];for i=1:n,x=[sortrows(x); f(n,i)*i-1/(f(n,i)*i)+abs(f(n,i)-i) i f(n,i)];end,x(1,2:3)
  • astuce 1: j'ai ajouté le montant 1-1/length*widthcomme pointage

  • astuce 2: j'ai calculé le number_students/lengthplafond pour la largeur du rectangle, la limite supérieure est le carré mais aussi le plafond

  • Je suis sûr qu'il peut être joué plus loin ...

essayez-le


Edit: référencé aux remarques de @StewieGriffin.

Modifier 2:

  • 1et nsont des constantes pas besoin de les ajouter au score global.
  • Une fonction représente quelques octets de moins qu'un programme autonome stdin.
  • J'ai cependant utilisé une technique de tri ascendant qui économise trop d'octets.

Edit 3: test de performance.

Abr001am
la source
@StewieGriffin qui n'est pas un gros problème, il peut être résolu en utilisantunique
Abr001am
1
je pense que je suis à mi-chemin d'une belle traduction mathématique pour ce problème, mais cela reste une conjecture
Abr001am
J'ai aussi pensé à ça. Voir l'exemple de julia.
mschauer
1

Python 2, 64 octets

lambda n:max((~-i*~min(i,n/i),0-n/i,-i)for i in range(-n,0))[1:]

Il s'agit d'une fusion de la réponse Python de @ Lynn (d'où j'ai pris l' max(...)[1:]astuce) et de l'algorithme de ma réponse Julia (qui permet une implémentation légèrement plus courte).

Testez-le sur Ideone .

Dennis
la source
1

Julia, 61 59 55 53 52 octets

/ =cld
n->[m=indmax([~i*~-max(i,n/i)for i=1:n]),n/m]

Essayez-le en ligne!

Comment ça fonctionne

Le code est équivalent à la version non golfée suivante, où cldest la division du plafond.

function chairs(n)
    m = indmin([(i + 1) * (max(i, cld(n, i)) - 1) for i in 1:n])
    return [m, cld(n, m)]
end

Pour trouver l'arrangement optimal, il suffit clairement d'examiner les paires [i, j] , où 1 ≤ i ≤ n et j = ⌈n / i⌉ .

Le score pour un tel arrangement est | j - i | + (ij - n) , où la deuxième somme est le nombre de chaises vides. Au lieu des scores réels, nous pouvons comparer les scores augmentés d'une constante, tels que ij + | j - i | + 1 .

Il suffit de considérer les paires [i, j]i ≤ j puisque les dispositions [i, j] et [j, i] sont également valables. Nous traitons les paires strictement décroissantes en fixant j = max (⌈n / i⌉, i) à la place, ce qui garantit que j ≥ i et produira un score sous-optimal si ⌈n / i⌉ <i .

Puisque j - i ≥ 0 , on a ij + | j - i | + 1 = ij + j - i + 1 = (i + 1) × (j - 1) , qui peut être calculé en moins d'octets de code.

Enfin indmin/ indmaxdonne l'indice m (et donc la valeur de i ) de l'arrangement optimal, qui est m par ⌈n / m⌉ . Les liens sont rompus par première occurrence, ce qui correspond à la valeur la plus basse de i , donc la valeur la plus élevée de j - i et donc la valeur la plus basse de ij - n (chaises vides).

Dennis
la source
1

JavaScript (ES6) 74 78

Modifier en conservant le résultat temporaire sous forme de tableau au lieu de 2 vars, emprunté à la réponse de Thiht

n=>(z=>{for(x=0;y=-~(~-n/++x),x<=y;)(s=y-x+x*y-n)>=z||(z=s,r=[x,y])})()||r

Moins golfé

n=>{
  z = 1/0
  for (x=0; y=(n-1)/++x+1|0, x <= y; )
  {
    s = y-x+x*y-n;
    if (s<z)
      z=s, r=[x,y]
  }
  return r
}

Tester

f=n=>(z=>{for(x=0;y=-~(~-n/++x),x<=y;)(s=y-x+x*y-n)>=z||(z=s,r=[x,y])})()||r

out=x=>O.textContent+=x+'\n'

for(i=1;i<=100;i++)out(i+' :( '+f(i)+' )')
<pre id=O></pre>

edc65
la source
1

PHP, 129 octets

function f($i){$s=INF;for($x=1;$x<$i;$x++){if($s>$t=(abs($x-$e=ceil($i/$x))-$i+($e*$x))){$s=$t;$d[0]=$x;$d[1]=$e;}}var_dump($d);}

Non golfé:

function f ($i){
    $s=INF;
    for($x=1; $x<$i; $x++){ // for every number less than the input
        if( $s > $t=( abs($x-$e=ceil($i/$x))-$i+($e*$x) ) ){ 
            // determine the other dimension, the score, and compare to the minimum score
            $s=$t;
            $d[0]=$x;
            $d[1]=$e;
        }
    }
    var_dump($d);
}
Chat d'affaires
la source
1

PHP, 104 octets

L'algorithme qui résout ce problème est simple et il est probablement utilisé par d'autres réponses dans des langages similaires à PHP (JavaScript, fe):

  • commencez par une grande valeur pour le score initial; nest suffisamment grand (où nest la valeur d'entrée); le score de l'arrangement calculé sur la première itération ( 1, n) est (n-1)+0;
  • itérer pour toutes les valeurs de largeur entre 1et n; calculer la hauteur minimale comme ceil(n/width), calculer le score d'arrangement en utilisant la formule fournie dans la question (c.-à-d. abs(width - height) + (width * height - n)); si le score est meilleur que le meilleur score précédent, n'oubliez pas la largeur, la hauteur et le nouveau meilleur score; sur les liens, utilisez la valeur de width * height - npour l'arrangement actuel et l'ancien meilleur arrangement pour détecter le nouveau meilleur arrangement;
  • c'est tout.

Après le golf, cet algorithme produit quelque chose comme ça (enveloppé ici pour plus de lisibilité):

for($s=$h=$j=$n=$argv[$w=$i=1];$i<=$j;$j=ceil($n/++$i)
{$c=$j-$i+$i*$j-$n;if($c<$s||$c==$s&&$i*$j<$w*$h){$w=$i;$h=$j;$s=$c;}}
echo"$w,$h";

Il utilise 137 octets (lorsqu'il est mis sur une seule ligne) et il est loin des 104 octets annoncés dans le titre. Le code peut probablement être raccourci de 2-3 octets mais la grande source d'amélioration est ailleurs: dans les détails de l'algorithme.

L'algorithme révisé:

Il existe plusieurs endroits où l'algorithme peut être amélioré en supprimant le code inutile.

  • il n'est pas nécessaire d'itérer la largeur de 1à $n; pour la vitesse, la largeur ( $i) doit itérer entre 1et floor(sqrt($n))mais cela rend le code encore plus long au lieu de le raccourcir; mais si la largeur ne dépasse pas sqrt($n), la hauteur minimale ( $j) sera toujours supérieure à sqrt($n)(leur produit doit être au moins $n);
  • l'instruction précédente permet d'utiliser $i <= $j(largeur <= hauteur) comme condition de terminaison pour la boucle; de cette façon, la largeur itérera de 1à floor(sqrt($n))et la hauteur obtiendra des valeurs commençant par $net descendant vers ceil(sqrt($n))(pas nécessairement toutes);
  • sachant que la largeur est toujours inférieure ou égale à la hauteur nous permet de savoir que abs(width - height)c'est toujours height - width($j-$i ); 5 octets enregistrés de cette façon;
  • la valeur d'entrée $nest utilisée dans le calcul du score (le nombre de sièges inoccupés est width * height - n) mais elle n'est pas nécessaire; la partition n'a pas besoin d'être affichée, elle n'est calculée que pour la comparaison des arrangements; en supprimant - nde la formule de score, nous économisons encore 3 octets (le code PHP l'est -$n) sans rien perdre;
  • étant donné les deux derniers énoncés, la formule de score devient height - width + width * height( $j-$i+$i*$j);
  • sur les égalités (le score de l'arrangement actuel est le même que le meilleur score précédent), les règles disent d'utiliser l'arrangement avec moins de places libres; parce que la largeur augmente toujours et la hauteur diminue toujours, la height - widthpartie du score diminue à chaque pas;
  • si le score actuel est égal au meilleur score précédent, les déclarations précédentes nous indiquent que le nombre de places libres de l'arrangement actuel est plus grand que celui du meilleur arrangement précédent; cela signifie que le meilleur arrangement précédent a remporté l'égalité;
  • parce que les égalités sont toujours gagnées par le meilleur arrangement précédent, un nouvel arrangement ne devient le nouveau meilleur arrangement que lorsque son score est inférieur au meilleur précédent; le code qui vérifie les liens est inutile et peut être supprimé ( ||$c==$s&&$i*$j<$w*$h- beaucoup d'octets);
  • en raison de la suppression de -$nde la formule du score, le score pour le premier arrangement ( 1x$n) est $n-1+1*$n(ie 2*$n-1); la valeur initiale du meilleur score ( $s) peut être toute valeur supérieure ou égale à 2*$n; la première itération a un meilleur score et devient le meilleur arrangement permettant à l'algorithme de fonctionner sans problèmes d'initialisation.

Le nouveau code ( 104 octets ), après avoir appliqué les améliorations décrites ci-dessus, est:

for($s=2*$j=$n=$argv[$i=1];$i<=$j;$j=ceil($n/++$i))
if($s>$c=$j-$i+$i*$j){$w=$i;$h=$j;$s=$c;}echo"$w,$h";

Il est emballé ici pour plus de lisibilité. Ajoutez le code ci-dessus avec le marqueur PHP <?php(techniquement, il ne fait pas partie du code), placez-le dans un fichier (disons arrange-your-chairs.php) et exécutez-le avec un entier supérieur à zéro comme argument. Il affichera la largeur et la hauteur de l'arrangement calculé, séparées par une virgule:

$ php arrange-your-chairs.php 1001
28,36

Une autre solution (116 octets)

Une autre solution qui utilise un algorithme différent:

for($n=$argv[1];++$j<=$n;)for($i=0;++$i<=$j;)
if($n<=$k=$i*$j)$a["$i,$j"]=($j-$i+$k-$n)*$n+$k;asort($a);echo key($a);

Il place toutes les combinaisons d'au moins des $nsièges dans une liste associative; la clé est la représentation textuelle de l'arrangement, la valeur est le score de l'arrangement. Il trie ensuite la liste (croissant par valeur) et obtient la clé de la première entrée.

Un de plus (115 octets)

foreach(range(1,$m=$n=$argv[1])as$i)
if(($d=ceil($n/$i))<=$i&&$m>=$s=$i*$d-$n+$i-$d){$m=$s;$w=$d;$h=$i;}echo"$w,$h";

Ceci est la version PHP de la réponse de @ Neil (JavaScript / ES6, 85 octets).

Il existe des différences notables en raison des caractéristiques de chaque langue:

  • la réponse JS génère un tableau de nvaleurs (non définies) puis utilise ses clés pour itérer de 0à n-1; il incrémente i( d=(n+i++)/i|0) pour le faire itérer de 1à n; la solution PHP n'a pas besoin d'incrémenter; il utilise range()pour générer un tableau puis il utilise les valeurs générées ( 1à n) pour itérer;
  • la réponse JS utilise (n+i)/iconvertit ensuite la valeur en entier en utilisant |0pour obtenir le plus petit entier plus grand que n/i; la réponse PHP résout facilement ce problème avec la fonction PHP ceil(); JavaScript fournit également, Math.ceil()mais il utilise 5 octets de plus que la solution trouvée par Neil;
  • PHP fournit la fonction array_map()qui est en quelque sorte similaire à JS Array.map()mais cela n'aide pas ici; sa syntaxe est verbeuse, a foreachproduit un code plus court; il est cependant plus grand que le code JS;
  • la fusion des affectations dans les conditions utilisant ||n'est pas possible en PHP car il manque l'opérateur virgule; Je traduis a||b||cen if(!a&&!b)cpuis, parce que aet bdes comparaisons, je leurs opérateurs nié (remplacé <par >=); cela produit également un code plus volumineux que la version JS;
  • 23 octets supplémentaires doivent être ajoutés juste parce que les noms des variables en PHP doivent être préfixés par $.

Les versions non golfées de toutes les solutions et la suite de tests peuvent être trouvées sur Github .

axiaque
la source
1
C'est la réponse de golf par code la plus complète que j'ai jamais vue.
DJMcMayhem
0

JavaSCript (ES6), 83 octets

n=>[...Array(m=n)].map((_,i)=>(d=(n+i++)/i|0)>i||(s=i*d-n+i-d)>m||(m=s,r=[d,i]))&&r
Neil
la source
Vous pourriez peut-être appliquer mon astuce (pour économiser 2 octets)
Leaky Nun
@KennyLau Je ne pense pas que cela aide; Je devrais augmenter mpour compenser.
Neil
0

Julia, 87

Je pense que c'est un pas vers la recherche d'une fonction magique pour le problème:

f(i)=(i+n)÷(i+1)|>j->(j*i<n)+j
_=indmin([sqrt(n)<=i?i-f(i)*(1-i):2n for i=1:n])
_,f(_)

Il ne regarde que les paires (i, j=(i+n)/(i+1))ou(i, j+1)

mschauer
la source
veuillez expliquer comment cela fonctionne, vous m'avez rendu curieux de
connaître
2
Je ne sais pas comment cela est censé fonctionner. Vous ne définissez nnulle part et vous ne semblez pas prendre de contribution.
Dennis
Ah, désolé, je viens de prendre ncomme entrée. Il faudrait l'envelopper n->.... Ravi que vous puissiez le faire fonctionner.
mschauer
0

Oracle SQL 11.2, 173 octets

SELECT MIN(x||','||y)KEEP(DENSE_RANK FIRST ORDER BY y-x+(y*x-:1))FROM(SELECT CEIL(LEVEL/:1)x,CEIL(MOD(LEVEL+.1,:1))y FROM DUAL CONNECT BY LEVEL<=:1*:1)WHERE x<=y AND:1<=x*y;

Non golfé

SELECT MIN(x||','||y)KEEP(DENSE_RANK FIRST ORDER BY y-x+(y*x-:1))  -- Keeps the minimal score
FROM   (SELECT CEIL(LEVEL/:1)x,CEIL(MOD(LEVEL+.1,:1))y FROM DUAL CONNECT BY LEVEL<=:1*:1) -- Generate x,y combinations 
WHERE  x<=y AND :1<=x*y  -- Filters out wrong combinations
Jeto
la source
0

Q 58 octets

{c@d?&/d:+/(-/;*/)@\:+c:{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}x}

Lamba qui calcule le coût minimal pour une valeur donnée (x) et renvoie une séquence de deux valeurs (largeur, hauteur)

L'ajout d'un nom à ce lambda nécessite deux autres caractères (ex f: {..} au lieu de {..})

Tester

{..}'1+!100

où {..} est le lambda. Lire comme "applique lambda à chaque valeur de 1 + 100 premiers pouces" (en d'autres termes à chaque valeur 1..100)

Génère

1 1
2 1
2 2
2 2
3 2
3 2
3 3
3 3
3 3
5 2
4 3
4 3
4 4
4 4
4 4
4 4
6 3
6 3
5 4
5 4
7 3
5 5
..

Explication

La lamdba imbriquée {((b<a)?1b)#+(b:-_-x%a;a:1+!x)}génère toutes les paires candidates (largeur, hauteur) pour les chaises x sous la forme de deux séquences (w1 w2 w3 ..; h1 h2 h3 ..) (largeurs et hauteurs). Lire de gauche à droite, mais évaluer de droite à gauche

a:1+!x génère des valeurs 1..x et affecte cette séquence à un

-_- is negate floor negate, et implémente ceil (ceil n'est pas une primitive du langage)

b:-_-x%aapplique le plafond à chaque valeur de x divisée par un élément im a et attribue la séquence résultante à b. En d'autres termes, b est ceil chaque x divisé par chaque 1..x

+(b;a) retourner une sécuence composée de seq a et seq b, puis la retourne (le résultat est une séquence de paire où i-pair contient l'élément i de a et l'élément i de b)

b<a compare item par item de b et a, et génère une sécuence de valeurs logiques (true = 1b pour chaque index où b [i]

s?xrenvoie la première position de l'élément x dans la séquence s. Avec (b<a)?1bNous recherchons 1b (valeur vraie) dans la séquence résultant de la comparaison de b et a, et obtenons la première position où b

n#sprend n premiers n éléments des séquences. Nous voulons éliminer les paires en double, donc nous nous arrêtons lorsque le premier élément d'une paire <le deuxième élément (par exemple, considérons 13,1 mais pas 1,13).

Comme effet secondaire, chaque paire de la séquence résultante a une distance décroissante entre a et b (ex (13 1; 7 2; 5 3; 4 4)

La paire candidate générée par lambda imbriquée est affectée à c. Nous inversons ensuite c (obtient à nouveau b, a) et appliquons deux fonctions à cet argument: */multiplie et -/soustrait. Le résultat (-/;*/)@\:+cest la différence et le produit de chaque paire. +/est la somme terminée et calcule le coût final. Le coût de chaque patir est attribué à d

& / est un minimum sur, donc &/d est le coût minimum. Avec d?&/dnous trouvons la première occurrence de coût minimum en d, et avec c @ .. nous récupérons la paire à cette position. Comme chaque paire est de distante décroissante entre a et n, le premier minimum trouvé a le distante maximum entre les autres paires minimales, donc nous appliquons correctement la règle de lien

J. Sendra
la source