Diese Frage handelt von abelsche Sandhaufen . Lesen Sie diese vorherige Herausforderung und sehen Sie sich dieses Numberphile-Video an, um mehr zu erfahren.
Ein abelianischer Sandhaufen von Größe n mal n ist ein Gitter mit den Zahlen 0, 1, 2 und 3 (für die Anzahl der Sandkörner). Das Hinzufügen von zwei Sandhaufen funktioniert, indem Sie zuerst Element für Element hinzufügen und dann jedes Element stürzen , das über 3 hinausgeht. Die Reihenfolge, in der Sie stürzen, spielt keine Rolle, das Endergebnis ist dieselbe. Wenn eine Zelle umkippt, verringert sich ihre Anzahl um 4 und jeder ihrer direkten Nachbarn erhöht sich um 1. Dies kann eine Kettenreaktion verursachen. Befindet sich eine Zelle am Rand des Gitters, verschwinden alle Körner, die beim Umkippen vom Gitter fallen.
Zum Beispiel füge ich zwei 3 mal 3 Sandhaufen hinzu (was eine ziemlich extreme Kettenreaktion ergibt):
3 3 3 1 2 1 4 5 4 4 6 4 6 2 6 6 3 6 2 5 2 4 1 4 4 2 4 0 4 0 2 0 2 2 1 2
3 3 3 + 2 1 2 = 5 4 5 -> 6 0 6 -> 2 4 2 -> 3 0 3 -> 5 0 5 -> 1 4 1 -> 2 0 2 -> 4 0 4 -> 0 4 0 -> 1 0 1
3 3 3 1 2 1 4 5 4 4 6 4 6 2 6 6 3 6 2 5 2 4 1 4 4 2 4 0 4 0 2 0 2 2 1 2
In dieser Herausforderung sind wir in einer Teilmenge aller möglichen interessieren n von n sandpiles. Diese Untermenge enthält alle Sandpiles, die Sie erhalten können, indem Sie den all-3s n einen beliebigen Sandpile hinzufügen by n erhalten können . Zum Beispiel haben wir oben gesehen, dass dies 212 | 101 | 212
in der Teilmenge enthalten ist, weil wir es durch Hinzufügen von etwas zum Sandhaufen all-3 erhalten haben.
Jetzt hat diese Untergruppe ein interessantes Element: das Identitätselement . Wenn Sie dieses Element zu einem anderen Element in der Teilmenge hinzufügen , bleibt die Summe unverändert. Mit anderen Worten verhält sich dieser Sandhaufen wie eine Null dieser Teilmenge. Zufällig 212 | 101 | 212
ist dies das Null-Element für die Teilmenge von 3 mal 3. Zum Beispiel:
2 2 2 2 1 2 4 3 4 0 5 0 2 1 2 2 2 2
2 2 2 + 1 0 1 = 3 2 3 -> 5 2 5 -> 1 6 1 -> 2 2 2
2 2 2 2 1 2 4 3 4 0 5 0 2 1 2 2 2 2
Nun ist dies Ihre Herausforderung: gegebene n , das Identitätselement der Teilmenge des finden n durch n Gitter . Geben Sie es aus, indem Sie jedem 0, 1, 2, 3
Bild eine eindeutige Farbe mit einem ausreichenden Kontrast Ihrer Wahl zuweisen und ein n-mal-n-Bild ausgeben. Ihr Code muss in der Lage sein, auf einem vernünftigen modernen PC das 50 mal 50-Gehäuse in weniger als einer Minute zu erstellen.
Zum Beispiel das Identitätselement 500 x 500:
Hier ist Blau = 3, Grün = 2, Rot = 1, Weiß = 0. Aber Sie müssen dieses Farbschema in Ihrer Antwort nicht verwenden.
Antworten:
Oktave,
120113 BytesVielen Dank an JungHwan Min für den Link zum Referenzpapier in seiner Mathematica-Antwort.
Vielen Dank an Stewie Griffin ich 7 Bytes gespart
[any(any(x)) -> nnz(x)]
Hier werden zwei Funktionen verwendet:
1
f
.: zur Stabilisierung einer Matrix2. Eine anonyme Funktion, die übernimmt
n
als Eingabe dient und die Identitätsmatrix anzeigt.Probieren Sie es auf rextester!zur Erzeugung einer 50 * 50-Matrix
Verstrichene Zeit für die Berechnung der Matrix:
0.0844409 seconds
.Erläuterung:
Betrachten Sie eine Funktion
f
, die eine Matrix stabilisiert. Die Aufgabe, die Identität zu finden, ist einfachf(ones(n)*6 - f(ones(n)*6)
.Das
ones(n)*6
bedeutet eine * n Matrix von 6.also für
n=3
:Das Ergebnis wird sein
f(M-f(M))
Für die Stabilisierungsfunktion wird eine 2D-Faltung verwendet, um die Aufgabe zu beschleunigen. In jeder Iteration erstellen wir eine binäre Matrix
b
mit der gleichen Größe der Eingabematrix und setzen sie auf 1, wenn das entsprechende Element der Eingabematrix> 3 ist. Dann wenden wir eine 2D-Faltung der binären Matrix mit der folgenden Maske anVertretung von vier direkten Nachbarn.
Das Ergebnis der Faltung wird zur Matrix addiert und die 4-fache binäre Matrix davon subtrahiert.
Die Schleife wurde fortgesetzt, bis alle Elemente der Matrix <= 3 sind
Ungolfed-Version :
quelle
Mathematica,
177157135133 BytesNimmt eine Nummer
n
. Die Ausgabe ist der Identitätssandhaufen. 0 ist schwarz, 1 ist hellgrau, 2 ist magenta und 3 ist blaugrau.Leider hat Mathematica keine eingebaute ...
Verwendet den Algorithmus von Scott Corry und David Perkinson .
Die Berechnung des 50x50-Identitätssandstapels auf meinem 5 Jahre alten Laptop dauert 91,7 Sekunden. Ich bin zuversichtlich, dass ein vernünftiger moderner Desktop-Computer mehr als 50% schneller ist. (Ich habe auch einen viel schnelleren Code am Ende).
Erläuterung
Funktion definieren
f
(die Eingabe ist eine Sandpile-Matrix): eine Funktion, die ...... wiederholt den
BlockMap
Vorgang, bis sich der Ausgang nicht mehr ändert.BlockMap
Operation: ...... das Eingangsarray mit einer Ebene von 0 auffüllen ...
... partitioniere es in 3x3 Matrizen mit Offset 1 ...
... und für jede Partition die Anzahl der auf die mittlere Zelle gestürzten Sandkörner und den mittleren Zellenwert mod 4 addieren.
dh die Ausgabe von
f
ist die stabilisierte Version der Eingabe.Definieren
k
als n von n Array von 6s.Berechnen Sie f (k - f (k)).
Wenden Sie Farben auf das Ergebnis an.
Schnellere Version (142 Bytes)
Gleicher Code, aber stattdessen integrierte Listendrehung
BlockMap
. Berechnet n = 50 in 4,0 Sekunden auf meinem Laptop.quelle
Python 3 + Numpy + PIL,
385370364 BytesÜbernimmt die Eingabe für STDIN. Gibt das Bild in Graustufen aus
i.png
. Schwarz entspricht 0, Dunkelgrau 1, Hellgrau 2 und Weiß 0.Verwendet die Formel
I = R(S - R(S))
, wobeiI
das IdentitätselementS
ist, die mit Sechsern gefüllte Matrix undR
die Reduktionsfunktion ist.Ich könnte wahrscheinlich einige Bytes sparen, indem ich zu Python 2
from numpy import*
wechsle und dies tue , aber (1) ich habe Numpy nicht auf Python 2 installiert und (2) das Programm wurde nicht beendetfrom numpy import*
.Ungolfed:
quelle
scipy
oder verwendenmatplotlib
, um die Daten anzuzeigen, anstatt ein Bild explizit mit PIL zu generieren.