Betrachten Sie eine Permutation der ganzzahligen Werte von 1
bis N
. ZB dieses Beispiel für N = 4
:
[1, 3, 4, 2]
Wir werden diese Liste prüfen sein zyklisch, so dass 1
und 2
wie benachbarte behandelt. Eine Größe, die wir für eine solche Liste berechnen können, ist die quadratische Gesamtdifferenz benachbarter Werte:
(1-3)² + (3-4)² + (4-2)² + (2-1)² = 10
Ihre Aufgabe ist es, eine Permutation zu finden, die diese Größe bei einer positiven ganzen Zahl maximiert N
. Im Falle des N = 4
obigen Beispiels ist es nicht optimal (in der Tat ist es minimal). Wir können eine quadratische Gesamtdifferenz von 18
mit der folgenden Permutation (wie auch mit mehreren anderen) erzielen :
[1, 4, 2, 3]
Ihr Algorithmus muss in Polynomialzeit (von N
) ausgeführt werden. Insbesondere können Sie nicht einfach die quadratische Gesamtdifferenz aller Permutationen berechnen.
Sie können ein Programm oder eine Funktion schreiben, indem Sie eine Eingabe über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), einen Funktionsrückgabewert oder einen Funktionsparameter (out) ausgeben.
Die Ausgabe kann in einem beliebigen praktischen, eindeutigen, einfachen Listen- oder Zeichenfolgenformat erfolgen. Sie können eine Liste mit Werten von 0
bis N-1
anstelle von 1
bis zurückgeben N
.
Es gelten die Standardregeln für Code-Golf .
Testdaten
Für dieses Problem gibt es eine gute analytische Lösung. ZB entsprechen alle gültigen Lösungen für N = 10
die folgende Liste (bis zu zyklischen Verschiebungen und Umkehrungen):
[7, 5, 6, 4, 8, 2, 10, 1, 9, 3]
Ich möchte nicht zu viel darüber hinaus verraten (obwohl es wahrscheinlich ausreicht, um das Muster herauszufinden). Anstatt weitere Beispiele zu nennen, können Sie überprüfen, ob Ihre Ergebnisse die folgenden quadratischen Gesamtdifferenzen für eine bestimmte Zahl aufweisen N
:
N Total squared difference
1 0
2 2
3 6
4 18
5 36
6 66
7 106
8 162
9 232
10 322
33 11936
100 333202
333 12308236
1000 333332002
Dies ist der OEIS-Eintrag A064842 (der auch einen Verweis auf ein Dokument mit einer Lösung für diese Herausforderung enthält, wenn Sie nicht weiterkommen).
quelle
(i<n/2||n%2)^i%2?i+1:n-i
.Python2,
10598 BytesDank des Kommentars von @Dennis wurden 7 Bytes gespart
Bearbeitete Version 58 Bytes
Ich war bereits der Meinung, dass es möglich sein sollte, dies als Einzeiler zu tun, aber die Logik war zu komplex für mich. Nachdem ich die JavaScript-Antwort von @ user81655 und die Lambda-Notation in @ Tennis Python-answer gesehen habe, habe ich es erneut versucht.
Die Bedingung ist gleich
Leider spart der gesamte Transformationsaufwand nur
einNo-Byte gegenüber der direkten Übersetzung(i<n/2or n%2)!=i%2
der JavaScript-Logik.quelle
int()
um die Eingabe nicht benötigen . Sie können den Körper der for-Schleife auch in dieselbe Zeile setzen wiefor...
.Python,
5149 BytesVielen Dank an @xnor für das Golfen mit 2 Bytes!
Probieren Sie es auf Ideone .
Wie es funktioniert
Wenn i eine Zahl in [0, ..., n - 1] ist , dann ist ~ i% n = - (i + 1)% n = - (i + 1) + n = (n - 1) - i , was bedeutet, dass es 0 auf n - 1 , 1 auf n - 2 und im Allgemeinen das j- te Element von links nach j- ten von rechts abbildet .
Wie in meiner Jelly-Antwort erläutert , können wir die Ausgabe konstruieren, indem wir den niedrigeren Wert zwischen i und ~ i% n betrachten und i auswählen, wenn er gerade ist, und ~ i% n, wenn er ungerade ist. Dies erreichen wir wie folgt.
Wenn die minimale gerade ist,
min(i,~i%n)%-2
wird nachgeben 0 , so XOR - Verknüpfung des Ergebnisses mit i ergeben wird i , und die Berechnung seiner Rest modulo n kehrt i .Wenn die minimale ungerade ist,
min(i,~i%n)%-2
wird ergeben -1 , so dass das Ergebnis eine XOR - Verknüpfung mit i nachgeben ~ i , so dass die gesamte Ausdruck ergibt ~ i% n wie gewünscht.quelle
(i^min(i,n+~i)%-2)%n
.PHP,
7776515049 BytesVerwendet ISO 8859-1-Codierung.
Setze die erste Hälfte des Arrays wie folgt zusammen:
N+1-index
(9, 7, 5)1, 9, 3, 7, 5
Wie für die zweite Hälfte des Arrays addieren sich die äußersten Werte
N+1
, was bedeutet, dass Sie den entsprechenden rechten Wert erhalten, vonN-[left value]
dem der linke Wert bereits bekannt ist.Gehen Sie wie folgt vor (dies zeigt auch die gesamte quadratische Differenz) (
-d
nur aus ästhetischen Gründen hinzugefügt):echo
~ß
, um ein Leerzeichen zu ergeben.quelle
Python 2, 100
Ich weiß, dass es bereits eine Python-Antwort gibt, aber ich glaube, dass ich das anders gemacht habe.
Und als Extra zum Testen der Gesamtpunktzahl:
quelle
def t(x,n):return sum((x[i]-x[i-1])**2for i in range(n))
Verwendet das implizite Umbrechen von negativen Indizes und speichert 4 Bytes. Ich weiß, war nicht Teil des Wettbewerbs. ;)CJam,
171514 BytesDies ist eine Funktion, die eine Ganzzahl n aus dem Stapel entfernt und eine Permutation von [0… n-1] zurückgibt. Der Code verwendet den gleichen Ansatz wie meine Gelee-Antwort .
Probieren Sie es online!
Wie es funktioniert
quelle
LISP, 86 Bytes
Mit den Eingängen der Funktion können Sie den Anfangswert (m) und den Endwert (n) der Sequenz auswählen.
Zum Testen der Funktion gemäß den bereitgestellten Mustern wird n auf N und m auf 1 festgelegt.
Hier der Code zum Testen der Funktion:
Probieren Sie es auf Ideone !
quelle
Julia, 39 Bytes
Dies gibt eine Permutation von 1: n aus . Eine Permutation von 0: n-1 kostet und spart keine Bytes:
Diese letzte Version ist ein direkter Port meiner Python-Antwort .
quelle
ES6, 77 Bytes
Dabei werden
i&1
die Ziffern von den Extremen bis zur Mitte abgetastet. Dasi&2
fügt sie paarweise an den Anfang oder das Ende des Ergebnisses an.quelle
R
11786 Bytesbearbeiten ersetzt Buggy lange Version mit einer Implementierung von @ Dennis Jelly - Algorithmus
quelle