Sie unterrichten eine Klasse von Schülern mit interessanten Präferenzen für die Anordnung ihrer Stühle. Es gibt 3 sehr spezifische Anforderungen an die Anordnung der Stühle:
Sie werden meist in einem Rechteck angeordnet, auch wenn dadurch einige Stühle leer werden.
Es müssen so wenig Stühle wie möglich frei sein.
Sie müssen so quadratisch wie möglich sein. Die Rechteckigkeit wird durch den Abstand zwischen der Breite und der Höhe des Rechtecks bestimmt, niedriger ist besser. Beispiel: Ein Rechteck
4x7
hat eine Quadratzahl von 3.
Genauer gesagt ist die "Punktzahl" einer Anordnung der Abstand zwischen der Breite und der Höhe plus der Anzahl der Stühle, die leer gehen würden.
Nehmen wir ein Beispiel. Angenommen, Sie haben 13 Schüler. Sie können die Stühle folgendermaßen anordnen:
1x13
2x7
3x5
4x4
1x13
ist nicht sehr quadratisch. Tatsächlich sind 1 und 13 12 voneinander entfernt, daher geben wir dieser Anordnung 12 Punkte. Es hat auch 0 leere Stühle, also addieren wir 0 Punkte, was diesem Arrangement eine Punktzahl von 12 gibt. Nicht so toll.
2x7
ist sicherlich besser. 2 und 7 sind nur 5 voneinander entfernt, daher geben wir dieser Anordnung 5 Punkte. Wenn Sie jedoch zwei Reihen mit sieben Stühlen arrangieren würden, würde dies 14 Stühle einnehmen, was bedeutet, dass ein Stuhl leer wäre. Also addieren wir einen Punkt und geben diesem Arrangement eine Punktzahl von 6.
Wir könnten es auch tun 3x5
. 3 und 5 sind 2 auseinander, also +2 Punkte. Es werden 15 Stühle benötigt, was bedeutet, dass wir zwei zusätzliche Stühle haben, also weitere +2 Punkte für eine Punktzahl von 4.
Letzte Option 4x4
. 4 und 4 sind 0 auseinander, also geben wir diese +0 Punkte. 4x4 nimmt 16 Stühle ein, sodass 3 Stühle leer sind, was eine Gesamtpunktzahl von 3 ergibt. Dies ist die optimale Lösung.
Im Falle eines Unentschieden ist die optimale Lösung die mit weniger leeren Stühlen.
Die Herausforderung
Sie müssen ein Programm oder eine Funktion schreiben, die eine Ganzzahl annimmt und die optimale Anordnung der Lehrstühle für diese Anzahl von Schülern ausgibt. IO kann in jedem vernünftigen Format vorliegen. Hier ist eine Beispielausgabe für eine beliebige Anzahl von Schülern von 1 bis 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)
Wie üblich ist dies Codegolf, daher gelten Standardlücken, und der Gewinner ist die kürzeste Antwort in Bytes.
Antworten:
Jelly ,
161514 BytesProbieren Sie es online! oder überprüfen Sie alle Testfälle .
Wie es funktioniert
quelle
Python 2, 68 Bytes
Gleichbedeutend mit dem Offensichtlicheren:
quelle
range(-n,0)
, wie ich es in meiner Antwort tue . Testsuite.Haskell, 65 Bytes
Anwendungsbeispiel:
map f [1..5]
->[(1,1),(1,2),(2,2),(2,2),(2,3)]
.Durchläuft eine äußere Schleife
a
von1
bisx
(x -> Anzahl der Schüler) und eine innere Schleifeb
von1
bisa
. Bewahrt alle Positionen(b,a)
aufa*b>=x
und bildet Paare,((arrangement points,seats left), (b,a))
die der lexikografischen Reihenfolge folgen, in der wir das Minimum finden müssen. Hinweis:a
ist immer größer alsb
, daher brauchen wir keineabs
Quadratmeter. Es ist nicht erforderlich,x
von der Punktzahl "Plätze übrig" abzuziehen , da nur die relative Reihenfolge von Bedeutung ist. Zum Schluss entfernen wir das Score-Paar mitsnd
.quelle
a*b
(Anzahl der freien Plätze) ist der Gleichstand, wenn die Hauptpunktzahl gleich ist. Zum Beispieln=43
: a)a=7, b=7
, Partitur:(49,49)
b)a=9, b=5
, score:(49,45)
. Hauptpunktzahl ist gleich, Tie Breaker entscheidet, b) gewinnt.a*b
, wirken die Nummern selbst,(b,a)
die ich sowieso herumtragen muss, als Kabelbinder und ergeben (zumindest) die gleichen Ergebnissen=1..300
. Ein Produkt ist klein, wenn einer der Faktoren (hierb
) klein ist. Aber solange ich keine formalen Beweise habe, möchte ich diese Tatsache nicht nutzen. Mal sehen, ob ich einen finde.Ruby, 64 Bytes
Eine Lambada, die die Anzahl der Personen als Argument verwendet und ein Array mit der Breite und Höhe der optimalen Lösung zurückgibt.
quelle
w*h
als zweites Element in Ihrem Array? Ich denke nicht, dass es etwas besonders ändert, wenn Sie anrufen,min
weil Sie die Punktzahl, auch bekannt als das erste Element, minimieren.In case of a tie, the optimal solution is the one with less empty chairs
MATL , 18 Bytes
Probieren Sie es online!
Erläuterung
quelle
Javascript, 98 Bytes
Mein erster Code Golf, also poste ich trotzdem!
Anfänglich war mein
o
Objekt leer und ich habe geprüft, obo.a
es leer war, also war es ein Sonderfall in der ersten Runde. Aber ich habe den 1/0-Trick in edc65's Antwort gefunden, um die Variable auf Unendlich zu initialisieren.quelle
Pyth,
242221 BytesBearbeiten : Im Sortierschlüssel stelle ich fest, dass die Anzahl der leeren Stühle nicht ermittelt werden muss. Dies entspricht der Gesamtzahl der Stühle. Das hat mir 2 Bytes gespart.
Probieren Sie es online!
quelle
Matlab
(174) (146)121trick 1: ich habe den betrag
1-1/length*width
als unentschieden addierttrick 2: ich habe die
number_students/length
decke für die breite des rechteckes berechnet , dieobere grenze ist das quadrat, aber auch die deckeIch bin sicher, es kann weiter golfen werden ...
Versuch es
Bearbeiten: auf die Ausführungen von @StewieGriffin verwiesen.
Bearbeiten 2:
1
undn
sind Konstanten, die nicht zur Gesamtpunktzahl addiert werden müssen.Edit 3: Leistungstest.
quelle
unique
Python 2, 64 Bytes
Dies ist eine Zusammenführung von @Lynns Python-Antwort (von wo ich den
max(...)[1:]
Trick genommen habe) und dem Algorithmus aus meiner Julia-Antwort (die eine etwas kürzere Implementierung ermöglicht).Teste es auf Ideone .
quelle
Julia,
6159555352 BytesProbieren Sie es online!
Wie es funktioniert
Der Code entspricht der folgenden ungolfierten Version, bei der
cld
es sich um eine Deckeneinteilung handelt.Um die optimale Anordnung zu finden, ist es eindeutig ausreichend, die Paare [i, j] zu untersuchen , wobei 1 ≤ i ≤ n und j = ⌈n / i⌉ .
Die Punktzahl für eine solche Anordnung ist | j - i | + (ij - n) , wobei der zweite Summand die Anzahl der leeren Stühle ist. Anstelle der tatsächlichen Ergebnisse können wir Ergebnisse vergleichen, die durch eine Konstante wie ij + | j - i | + 1 .
Es ist ausreichend, Paare [i, j] zu betrachten, bei denen i ≤ j ist, da die Anordnungen [i, j] und [j, i] gleichermaßen gültig sind. Wir beschäftigen uns mit streng absteigenden Paaren, indem wir stattdessen j = max (⌈n / i⌉, i) setzen , was sicherstellt, dass j ≥ i ist und eine suboptimale Punktzahl ergibt, wenn ⌈n / i⌉ <i ist .
Da j - i ≥ 0 ist , haben wir ij + | j - i | + 1 = ij + j - i + 1 = (i + 1) × (j - 1) , was in weniger Codebytes berechnet werden kann.
Schließlich gibt
indmin
/indmax
den Index m (und damit den Wert von i ) der optimalen Anordnung an, der m mal ⌈n / m⌉ ist . Gleichstände werden beim ersten Auftreten gebrochen, was dem niedrigsten Wert von i entspricht , also dem höchsten Wert von j - i und damit dem niedrigsten Wert von ij - n (leere Stühle).quelle
JavaScript (ES6) 74
78Bearbeiten Sie, indem Sie das temporäre Ergebnis als Array anstelle von zwei Variablen speichern, die aus Thihts Antwort stammen
Weniger golfen
Prüfung
quelle
PHP, 129 Bytes
Ungolfed:
quelle
PHP, 104 Bytes
Der Algorithmus, der dieses Problem löst, ist einfach und wird wahrscheinlich von anderen Antworten in PHP-ähnlichen Sprachen (JavaScript, z. B.) verwendet:
n
ist groß genug (won
ist der Eingabewert); die Punktzahl der Anordnung, die bei der ersten Iteration (1, n
) berechnet wurde, ist(n-1)+0
;1
undn
; Berechnen Sie die Mindesthöhe wieceil(n/width)
folgt: Berechnen Sie die Anordnungspunktzahl mithilfe der in der Frage angegebenen Formel (dhabs(width - height) + (width * height - n)
). Wenn die Punktzahl besser ist als die vorherige beste Punktzahl, merken Sie sich die Breite, die Höhe und die neue beste Punktzahl. Verwenden Sie bei Verbindungen den Wert vonwidth * height - n
für die aktuelle Anordnung und die vorherige beste Anordnung, um die neue beste Anordnung zu ermitteln.Nach dem Golfen erzeugt dieser Algorithmus so etwas (zur besseren Lesbarkeit hier eingeschlossen):
Es verwendet 137 Bytes (wenn es in eine einzelne Zeile gesetzt wird) und ist weit von den 104 Bytes entfernt, die im Titel angegeben sind. Der Code kann wahrscheinlich um weitere 2-3 Bytes gekürzt werden, aber die Hauptverbesserungsquelle liegt an einer anderen Stelle: in den Details des Algorithmus.
Der überarbeitete Algorithmus:
Es gibt mehrere Stellen, an denen der Algorithmus verbessert werden kann, indem nutzloser Code entfernt wird.
1
bis zu iterieren$n
. für die Geschwindigkeit, die Breite ($i
müssen) durchlaufen zwischen1
undfloor(sqrt($n))
dies macht aber den Code noch länger , anstatt sie zu verkürzen; Wenn die Breite jedoch nicht überschritten wirdsqrt($n)
, ist die minimale Höhe ($j
) immer größer alssqrt($n)
(ihr Produkt muss mindestens sein$n
).$i <= $j
(width <= height) als Abbruchbedingung für die Schleife. Auf diese Weise wird die Breite von1
bis iteriert ,floor(sqrt($n))
und die Höhe erhält Werte, die mit beginnen$n
und bisceil(sqrt($n))
(nicht unbedingt alle) abfallen .abs(width - height)
immerheight - width
($j-$i
) ist. 5 Bytes auf diese Weise gespeichert;$n
wird für die Berechnung der Punktzahl verwendet (die Anzahl der nicht besetzten Plätze istwidth * height - n
), wird jedoch nicht benötigt. die Partitur muss nicht angezeigt werden, sie wird nur zum Vergleich der Arrangements berechnet; Durch Entfernen- n
aus der Bewertungsformel sparen wir weitere 3 Bytes (der PHP-Code ist-$n
), ohne etwas zu verlieren.height - width + width * height
($j-$i+$i*$j
).height - width
Teil der Partitur mit jedem Schritt ab.||$c==$s&&$i*$j<$w*$h
- viele Bytes).-$n
aus der Partiturformel ist die Partitur für die erste Anordnung (1x$n
)$n-1+1*$n
(dh2*$n-1
); Der Anfangswert der besten Bewertung ($s
) kann ein beliebiger Wert größer oder gleich sein2*$n
. Die erste Iteration hat eine bessere Punktzahl und ist die beste Anordnung, mit der der Algorithmus ohne Initialisierungsprobleme ausgeführt werden kann.Der neue Code ( 104 Byte ) nach Anwendung der oben beschriebenen Verbesserungen lautet:
Es wird hier zur besseren Lesbarkeit umbrochen. Stellen Sie dem obigen Code den PHP-Marker voran
<?php
(technisch gesehen ist er nicht Teil des Codes), fügen Sie ihn in eine Datei ein (sagen wir malarrange-your-chairs.php
) und führen Sie ihn mit einer Ganzzahl größer als Null als Argument aus. Hier werden Breite und Höhe der berechneten Anordnung durch Komma getrennt angezeigt:Eine andere Lösung (116 Bytes)
Eine andere Lösung, die einen anderen Algorithmus verwendet:
Alle Kombinationen von mindestens
$n
Sitzen werden in eine assoziative Liste aufgenommen. der Schlüssel ist die Textdarstellung des Arrangements, der Wert ist die Punktzahl des Arrangements. Anschließend wird die Liste sortiert (aufsteigend nach Wert) und der Schlüssel des ersten Eintrags abgerufen.Ein weiteres (115 Bytes)
Dies ist die PHP-Version von @ Neils Antwort (JavaScript / ES6, 85 Byte).
Es gibt einige bemerkenswerte Unterschiede aufgrund der Merkmale der einzelnen Sprachen:
n
(undefinierten) Werten und verwendet dann ihre Schlüssel, um von0
bis zu iterierenn-1
. es inkrementierti
(d=(n+i++)/i|0
), um es von1
zu iterierenn
; Die PHP-Lösung muss nicht erhöht werden. Es wird verwendetrange()
, um ein Array zu generieren. Anschließend werden die generierten Werte (1
ton
) zum Iterieren verwendet.(n+i)/i
using konvertiert dann den Wert in eine Ganzzahl, wobei verwendet wird|0
, um die kleinste Ganzzahl größer als zu erhaltenn/i
. Die PHP-Antwort löst dieses Problem auf einfache Weise mit der PHP-Funktionceil()
. JavaScript bietet auchMath.ceil()
, verwendet jedoch 5 Byte mehr als die von Neil gefundene Lösung.array_map()
ähnliche Funktion wie JSArray.map()
, hilft aber hier nicht weiter. seine Syntax ist wortreich, aforeach
erzeugt kürzeren Code; es ist jedoch größer als der JS-Code;||
ist in PHP nicht möglich, da der Komma-Operator fehlt. Ich übersetztea||b||c
inif(!a&&!b)c
dann, weila
undb
Vergleiche sind, negierte ich ihre Operatoren (ersetzt<
durch>=
); Dies erzeugt auch größeren Code als die JS-Version.$
.Die ungolfed Versionen aller Lösungen und der Testsuite sind auf Github zu finden .
quelle
JavaSCript (ES6), 83 Byte
quelle
m
, um zu kompensieren.Julia, 87
Ich denke, dies ist ein Schritt in Richtung einer magischen Funktion für das Problem:
Es sieht nur bei Paaren
(i, j=(i+n)/(i+1))
oder(i, j+1)
quelle
n
nirgendwo und scheinen keine Eingaben zu machen.n
als Eingabe genommen. Man müsste es einwickelnn->...
. Schön, dass Sie es zum Laufen bringen konnten.Oracle SQL 11.2, 173 Byte
Nicht golfen
quelle
Q 58 Bytes
Lamba, der minimale Kosten für einen bestimmten Wert berechnet (x) und eine Folge von zwei Werten (Breite, Höhe) zurückgibt
Das Hinzufügen des Namens zu diesem Lambda erfordert zwei weitere Zeichen (z. B. {..} anstelle von {..}).
Prüfung
wo {..} ist das Lambda. Lesen Sie als "Wendet Lambda auf jeden Wert von 1 + den ersten 100 Zoll an" (mit anderen Worten auf jeden Wert von 1..100)
Erzeugt
Erläuterung
Die verschachtelte Lamdba
{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}
generiert alle Kandidatenpaare (Breite, Höhe) für x Stühle als zwei Sequenzen (w1, w2, w3 ..; h1, h2, h3 ..) (Breiten und Höhen). Von links nach rechts lesen, aber von rechts nach links auswertena:1+!x
generiert Werte 1..x und ordnet diese Sequenz einem zu-_-
ist negate floor negate und implementiert ceil (ceil ist kein Primitiv der Sprache)b:-_-x%a
Wendet ceil auf jeden Wert von x dividiert durch ein beliebiges Element im a an und weist die resultierende Sequenz b zu. Mit anderen Worten, b ist ceil jedes x geteilt durch jedes 1..x.+(b;a)
Geben Sie eine aus seq a und seq b zusammengesetzte Folge zurück, und drehen Sie sie dann um (das Ergebnis ist eine Folge von Paaren, wobei i-pair das Element i von a und das Element i von b enthält).b<a
vergleicht Element für Element von b und a und generiert eine Folge von logischen Werten (true = 1b für jeden Index, wobei b [i]s?x
Liefert die erste Position von Item x in der Reihenfolge s. Mit(b<a)?1b
Wir suchen nach 1b (wahrer Wert) in der Folge, die sich aus dem Vergleich von b und a ergibt, und erhalten die erste Position, an der b stehtn#s
Nimmt n erste n Elemente aus der Folge s. Wir wollen doppelte Paare verwerfen, also stoppen wir, wenn der erste Gegenstand eines Paares <der zweite Gegenstand ist (zB 13,1, aber nicht 1,13).Als Nebeneffekt hat jedes Paar der resultierenden Sequenz einen abnehmenden Abstand zwischen a und b (ex (13 1; 7 2; 5 3; 4 4)
Das durch verschachteltes Lambda erzeugte Kandidatenpaar wird c zugewiesen. Wir kehren dann c um (erhalten b, a erneut) und wenden zwei Funktionen auf dieses Argument an:
*/
multiplizieren und-/
subtrahieren. Das Ergebnis von(-/;*/)@\:+c
ist die Differenz und das Produkt jedes Paares.+/
ist die Summe und berechnet die Endkosten. Die Kosten für jeden Patir werden d zugewiesen& / ist das Minimum, also sind
&/
d die minimalen Kosten. Mitd?&/d
finden wir das erste Auftreten von minimalen Kosten in d, und mit c @ .. erhalten wir das Paar an dieser Position. Da jedes Paar eine abnehmende Distanz zwischen a und n hat, hat das erste gefundene Minimum die maximale Distanz zwischen anderen minimalen Paaren, so dass wir die Bindungsregel korrekt anwendenquelle