Bestimmen Sie bei einer positiven ganzen Zahl N das Startmuster auf einem N x N-Gitter, das die längste nicht wiederholte Sequenz nach den Regeln des Spiels des Lebens ergibt, und enden Sie mit einem festen Muster (Zyklus der Länge 1), das auf einem Torus gespielt wird.
Das Ziel ist nicht das kürzeste Programm, sondern das schnellste.
Da die Welt endlich ist, geraten Sie irgendwann in eine Schleife und wiederholen so einen bereits besuchten Zustand. Wenn diese Schleife die Periode 1 hat, ist das Startmuster ein gültiger Kandidat.
Ausgabe: Startmuster und Gesamtzahl der eindeutigen Zustände in der Sequenz (einschließlich Startmuster).
Jetzt ist der 1x1-Torus etwas Besonderes, da eine Zelle als benachbart zu sich selbst betrachtet werden kann oder nicht, aber in der Praxis gibt es kein Problem, eine einzelne lebende Zelle stirbt in jedem Fall einfach (an Überfüllung oder Einsamkeit). Somit ergibt Eingang 1 eine Sequenz der Länge 2, wobei die Sequenz eine lebende Zelle ist und dann für immer tot ist.
Die Motivation für diese Frage ist, dass es sich um ein Analogon zur Funktion der beschäftigten Biber handelt, aber auf jeden Fall weniger komplex, da wir an das Gedächtnis gebunden sind. Dies wird eine schöne Sequenz sein, die auch in OEIS aufgenommen werden kann.
Für N = 3 ist die Sequenzlänge 3, jedes Muster auf der linken Seite erreicht ein vollständig schwarzes 3 × 3-Quadrat und stirbt dann. (Alle Muster, die Teil eines Zyklus sind, wurden entfernt.)
quelle
Antworten:
C ++ bis N = 6
Diese Technik konzentriert sich auf eine schnelle Next-State-Funktion. Jede Karte wird als Bitmaske mit N ^ 2 Bits dargestellt, und Bit-Twiddly-Tricks werden verwendet, um den nächsten Zustand für alle Zellen gleichzeitig zu berechnen.
next
kompiliert bis zu200100 Montageanweisungen für N <= 8. Dann führen wir einfach die Standard-Alles-versuchen-Zustände-bis-sie-wiederholen aus und wählen den längsten aus.Dauert einige Sekunden bis zu 5x5, einige Stunden für 6x6.
quelle
next
wenn Sie zählen anstatt zu sortieren.#define H(x,y){x^=y;y&=(x^y);}
und dann so etwas wieH(n1,n2);H(n3,n4);H(n5,n6);H(n7,n8);H(n1,n3);H(n5,n7);H(n2,n4);H(n6,n8);H(n1,n5);H(n3,n7);H(n2,n6);H(n2,n3);H(n2,n5); return n2 & (b | n1) & ~(n3|n4|n5|n6|n7|n8) & ALL;
Ich sehe folgende Lösungsansätze:
Next(board)
Funktion leicht umkehren können, sehen wir, dass dies einige Vorteile hat, wenn auch nicht so viele, wie ich ursprünglich gehofft hatte.Prev2
.Ich glaube nicht, dass ich durch die Mikrooptimierung mit dem Code von Keith Schritt halten kann, aber aus Gründen des Interesses werde ich posten, was ich habe. Dies löst N = 5 in ungefähr einer Minute auf einer 2-GHz-Maschine unter Verwendung von Mono 2.4 oder .Net (ohne PLINQ) und in ungefähr 20 Sekunden unter Verwendung von PLINQ; N = 6 läuft viele Stunden.
quelle
Faktor
Einige Zeitstatistiken:
Beim Testen von 5 stürzte die REPL ab. Hmph. Der ineffizienteste Teil des Programms ist wahrscheinlich die Funktionsspielsequenz. Vielleicht kann ich es später verbessern.
quelle