Skolem-Sequenzen
Eine Skolem-Sequenz ist eine Folge von 2n
Zahlen, bei der jede Zahl i
zwischen 1
und n
genau zweimal vorkommt und der Abstand zwischen den beiden Vorkommen von i
genau i
Schritte beträgt . Hier einige Beispiele für Skolem-Sequenzen:
1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5
Die folgenden Sequenzen sind keine Skolem-Sequenzen:
1 2 1 2 (The distance between the 1's is 2, not 1)
3 1 1 3 (The number 2 is missing)
1 1 2 1 1 2 (There are four 1's)
Zielsetzung
Schreiben Sie ein Programm, eine Funktion oder einen Ausdruck, um die Anzahl aller Skolem-Sequenzen einer bestimmten Länge zu zählen. Genauer gesagt ist Ihre Eingabe eine Ganzzahl n
, und Ihre Ausgabe ist die Anzahl der Skolem-Sequenzen mit einer Länge 2n
. Diese Sequenz hat einen OEIS-Eintrag . Für n = 0
kann kehren Sie entweder 0
oder 1
. Die ersten Werte, beginnend mit 0
, sind
0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768
Regeln und Wertung
Das ist Code Golf. Das Ausgabeformat ist im Rahmen der Vernunft lax.
0, 1, 0, 0, 6...
in deiner Frage? Ist das das Code-Snippet, wenn ja, welche Sprache ist das?0
? Wenn Sie0
als gültige Eingabe zugeben möchten, sollte die Ausgabe sein1
.Antworten:
GolfScript,
4846 ZeichenDie schnellere Version ( online testen ) - läuft relativ schnell, z. B.
n=8
dauert etwa zwei Sekunden. Und der gewählte Ansatz braucht wirklich wenige Charaktere.Diese Version funktioniert auch mit Bitmasken. Es baut das mögliche Ergebnisarray von 1 aufwärts auf, dh für
n=3
:Während einige Ergebnisse (wie 000011) zwei mögliche Fortsetzungen haben, haben andere (dh 001100) keine und werden aus dem Ergebnisarray entfernt.
Erklärung des Codes:
quelle
J-Ausdruck, 47 Zeichen
Beispiel:
Dauert
y=:5
auf meinem Computer ungefähr 30 Sekunden .Der Algorithmus ist so langsam wie möglich:
~.(i.!+:y)A.,~>:i.y
generiert jede Permutation von1 2 .. y 1 2 .. y
und entfernt doppelte Einträge((=&{:+.2-#@])#;.2)\"1
berechnet:(...)\"1
für jedes Präfix jeder Zeile:#;.2
zählt die Elemente vor jedem Auftreten des letzten Elements#@]
zählt die Anzahl der Zählungen (dh die Anzahl der Vorkommen des letzten Elements)=&{:
bestimmt die "Gleichheit" "der" letzten Elemente "der Zählliste und der ursprünglichen Liste.+.
ist ein logisches ODER.=&{:+.2-#@]
liest "entweder die letzten Elemente [der Zählliste und der ursprünglichen Liste] sind gleich, oder es gibt nur ein Element [in der Zählliste] anstelle von zwei".*/"1
Multipliziert (logisches UND) über die Zeilen der Konditionstabelle und bestimmt, welche Permutationen Skolem-Sequenzen sind.+/
summiert die Einsen und Nullen zusammen.quelle
GolfScript (46 Zeichen)
Dies ist ein Ausdruck, der Eingaben auf dem Stapel entgegennimmt. Um daraus ein vollständiges Programm zu machen, das Eingaben auf stdin übernimmt, stellen Sie vor
~
Es ist ziemlich ineffizient - die meisten Einsparungen, die ich beim Golfen von 56 ungolfed Chars erzielt habe, waren die Erweiterung des Loop-Bereichs auf eine Weise, die keine falschen Ergebnisse liefert, sondern eine Abfallberechnung durchführt.
Der Ansatz ist die bitweise Maskierung kartesischer Produkte. ZB (unter Verwendung von Binär für die Masken) für
n=4
den ungolfed Code würde das xor jedes Elements im kartesischen Produkt berechnet[00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]
. Ein Ergebnis mit 8 Bit konnte nur durch nicht überlappende Masken erzielt werden.Um die Größe und nicht die Geschwindigkeit zu optimieren, akkumuliert der Code Teilprodukte (
S1 u S1xS2 u S1xS2xS3 ...
) und macht jedes Produkt aus2n
Elementen und nicht nur aus Elementen,2n-1-i
die tatsächlich zu einer gültigen Sequenz beitragen können.Geschwindigkeit
Die Golfversion läuft
n=5
in 10 Sekunden auf meinem Computer und mehr als 5 Minuten inn=6
. Die ursprüngliche Version ohne Wolf berechnetn=5
in weniger als einer Sekunde undn=6
in etwa 1 Minute. Mit einem einfachen Filter für Zwischenergebnisse kannn=8
in 30 Sekunden berechnet werden . Ich habe es auf 66 Zeichen (als Programm - 65 Zeichen als Ausdruck) gespielt, während ich die Schleifen so eingeschränkt wie möglich gehalten und Zwischenkollisionen gefiltert habe:quelle
GolfScript, 49 Zeichen
Erwartet die Nummer
n
auf STDIN. Dies ist Code-Golf - versuchen Sie den Code nicht mitn
mehr als 5.quelle
Salbei, 70
Dies ist etwas kürzer als mein Original.
Wie es funktioniert:
Bei einer gegebenen 0/1-Matrix besteht das genaue Deckungsproblem für diese Matrix darin, eine Teilmenge der Zeilen zu finden, die (als ganze Zahlen) zum All-One-Vektor summieren. Zum Beispiel,
hat eine Lösung
Meine bevorzugte Herangehensweise an Probleme besteht darin, sie auf ein genaues Deckungsproblem zu übertragen. Skolem-Sequenzen erleichtern dies effizient. Ich mache ein genaues Deckungsproblem, bei dem Lösungen mit Skolem-Längensequenzen in Konflikt geraten
2n
. Für eine Zeile des Problems Zum Beispieln=6
istDabei bedeutet eine 1 in Position
a < n
, dass das Symbola
verwendet wird. Die verbleibenden Positionen entsprechen den tatsächlichen Positionen in der Sequenz. Eine genaue Abdeckung entspricht jedem Symbol, das genau einmal verwendet wird, und jeder Stelle, die genau einmal gefüllt wird. Jedes Symbolk
an einem Ort ist konstruktionsbedingtk
Leerzeichen von seinem Partner entfernt.In Sage
DLXCPP
handelt es sich um eine "Dance Links" -Implementierung, die das genaue Cover-Problem auf außergewöhnlich anmutige Weise löst. Es ist einer meiner Lieblingsalgorithmen überhaupt, und in Sage direkt an der Oberfläche zu sein, macht die kombinatorische Aufzählung zu einer Freude.quelle
len(list(...))
werden 4 Zeichen gespeichert.len(list(...))
für n = 16 rechnen würde . Und es würde die Laufzeit völlig töten.