Baue einen Sandhaufen

59

Ein abelscher Sandhaufen ist für unsere Zwecke ein unendliches Gitter mit ganzzahligen Koordinaten, anfangs ohne Sand. Nach jeder Sekunde wird ein Sandkorn bei (0,0) platziert. Wenn eine Gitterzelle 4 oder mehr Sandkörner enthält, wird gleichzeitig ein Sandkorn auf jeden der vier Nachbarn verschüttet. Die Nachbarn von (x, y) sind (x-1, y), (x + 1, y), (x, y-1) und (x, y + 1).

Wenn eine Zelle verschüttet wird, kann dies dazu führen, dass ihre Nachbarn verschüttet werden. Einige Fakten:

  • Diese Kaskade wird irgendwann aufhören.
  • Die Reihenfolge, in der die Zellen verschüttet werden, spielt keine Rolle. Das Ergebnis wird dasselbe sein.

Beispiel

Nach 3 Sekunden sieht das Raster so aus

.....
.....
..3..
.....
.....

Nach 4 Sekunden:

.....
..1..
.1.1.
..1..
.....

Nach 15 Sekunden:

.....
..3..
.333.
..3..
.....

Und nach 16 Sekunden:

..1..
.212.
11.11
.212.
..1..

Die Herausforderung

Schreiben Sie in möglichst wenigen Bytes eine Funktion, die eine einzelne positive ganze Zahl t annimmt und nach t Sekunden ein Bild des Sandstapels ausgibt .

Eingang

Eine einzelne positive ganze Zahl t in einem beliebigen Format.

Ausgabe

Ein Bild des Sandhaufens nach t Sekunden unter Verwendung der Zeichen

 . 1 2 3

Bearbeiten: Verwenden Sie vier beliebige Zeichen oder zeichnen Sie ein Bild. Wenn Sie nicht ".123" oder "0123" verwenden, geben Sie in Ihrer Antwort an, was die Zeichen bedeuten.

Anders als in den Beispielen sollte Ihre Ausgabe die minimale Anzahl von Zeilen und Spalten enthalten, die erforderlich sind, um den Teil des Sandstapels ungleich Null anzuzeigen.

Das heißt, für Eingang 3 sollte der Ausgang sein

 3

Für 4 sollte die Ausgabe sein

 .1.
 1.1
 .1.

Wertung

Es gilt die Standardgolfwertung.

Regeln

Es sind keine Sprachfunktionen oder Bibliotheken erlaubt, die bereits wissen, was ein Sandhaufen ist.

Bearbeiten: Der Ausgabebereich wurde bearbeitet, die Zeichensatzbeschränkung wurde vollständig aufgehoben. Verwenden Sie vier verschiedene Zeichen oder Farben, die Sie mögen.

Eric Tressler
quelle
2
Kann der Eingang t sein 0? Was ist dann die Ausgabe?
Luis Mendo
1
Ist es richtig, dass zu einem bestimmten Zeitpunkt mehrere Kaskaden hintereinander stattfinden können? Also passieren in diesem Zeitschritt immer wieder Kaskaden, bis jede Zelle wieder 3 oder weniger ist?
Fehler
2
@flawr: Ja, das wäre richtig. Betrachten Sie den Unterschied zwischen t = 15 und t = 16.
El'endia Starman
@LuisMendo Die Eingabe wird als positives t angegeben , daher ist Null keine gültige Eingabe.
Eric Tressler
1
Ist es WIRKLICH notwendig, .für leere Zellen zu haben ? Können wir 0eine gültige leere Zelle haben?
Andreï Kostyrka

Antworten:

56

R, 378 343 297 291 Bytes

Wie gewöhnlich gibt der Benutzer seine / ihre Eingabe über ein scan()(ich habe die Variable bereits verwendet t, nehmen wir zstattdessen), sodass die zweite Zeile separat gestartet werden sollte, und dann den Rest:

e=numeric
a=1%*%scan()
x=1
o=a>3
n=1
while(any(o)){
v=which(o,T)
if(any(v==1)){a=rbind(e(n+2),cbind(e(n),a,e(n)),e(n+2));x=x+1;n=n+2;v=which(a>3,T)}
q=nrow(v)
u=cbind(e(q),1)
l=v-u[,1:2];r=v+u[,1:2];t=v-u[,2:1];b=v+u[,2:1]
a[l]=a[l]+1;a[r]=a[r]+1;a[t]=a[t]+1;a[b]=a[b]+1
a[v]=a[v]-4
o=a>3}
a

Gibt einen Array, das den Wert enthält , abei tth Generation (0, 1, 2 oder 3).

Testfälle:

z=3
     [,1]
[1,]    3
z=4
     [,1] [,2] [,3]
[1,]    0    1    0
[2,]    1    0    1
[3,]    0    1    0
z=16
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    0    1    0    0
[2,]    0    2    1    2    0
[3,]    1    1    0    1    1
[4,]    0    2    1    2    0
[5,]    0    0    1    0    0

Es hilft uns, dass dieses Ding sowohl vertikal als auch horizontal symmetrisch ist, was bedeutet, dass der am weitesten links liegende Punkt eine Höhe von 4 erhält, was bedeutet, dass der am weitesten oben liegende, der am weitesten rechts liegende und der am weitesten unten liegende Punkt ebenfalls 4 sind.

Oh, und habe ich gesagt, dass Sie schöne Visualisierungen machen können?

Nach 1000 Tropfen:

Abelscher Sandhaufen nach 1000 Schritten

Nach 50000 Tropfen (~ 4 Sekunden):

Abelianischer Sandhaufen nach 50000 Schritten

Nach 333333 Tropfen (~ 15 Minuten):

Abelscher Sandhaufen nach 100000 Schritten

Sie können es auch zeichnen!

image(1:n,1:n,a,col=colorRampPalette(c("#FFFFFF","#000000"))(4), axes=F, xlab="", ylab="")

Dies dauerte 4 Sekunden für 10000 Iterationen, verlangsamt sich jedoch erheblich für größere Arrays (z. B. einige Minuten für 100000 Iterationen). Dies ist der Grund, warum es so langsam wird (ich schätze die Wachstumsrate wie in Wachstumsrateund erhalte τ (i) ≈689 · i ^ 1,08, daher ist die durchschnittliche Zeit pro zusätzlichem Korn, bis sich der gesamte Sandhaufen nach dem iSchritt absetzt, etwas größer als eins). , und die Gesamtzeit in Abhängigkeit von der Anzahl der Körner wächst etwas langsamer als quadratisch (T (i) ≈ 0.028 * i ^ 1.74):

Durchschnittliche Iteration, bis sich der Stapel gesetzt hat

Ungefähre Berechnungszeit

Und jetzt mit einer vollständigen Erklärung:

e=numeric # Convenient abbreviation for further repeated use
a=1%*%scan() # Creates a 1×1 array with a user-supplied number
x=1 # The coordinate of the centre
o=a>3 # Remember which cells were overflown
n=1 # Array height that is going to change over time
while(any(o)){ # If there is still any overflow
  v=which(o,T) # Get overflown cells' indices
  if(any(v==1)){ # If overflow occurred at the border, grow the array
    a=rbind(e(n+2),cbind(e(n),a,e(n)),e(n+2)) # Growing
    x=x+1 # Move the centre
    n=n+2 # Change the height
    v=which(a>3,T) # Re-index the overflowed cells
    }
  q=nrow(v) # See how many indices are overflown
  u=cbind(e(q),1) # Building block for neighbours' indices
  l=v-u[,1:2];r=v+u[,1:2];t=v-u[,2:1];b=v+u[,2:1] # L, R, T, B neighbours
  a[l]=a[l]+1;a[r]=a[r]+1;a[t]=a[t]+1;a[b]=a[b]+1 # Increment neighbours
  a[v]=a[v]-4 # Remove 4 grains from the overflown indices
  o=a>3} # See if still overflown indices remain
a # Output the matrix

Dies ist das erste Mal in meinem Leben, dass das Wachsen von Objekten (wie a <- c(a, 1)) so viel schneller geht, als eine große leere Matrix für Werte vorab zuzuweisen und sie allmählich mit einer Tonne nicht verwendeter Nullen zu füllen.

Aktualisieren. 18 Bytes golfed durch Entfernen arr.indin whichdurch Billywob und Ersetzen rep(0,n)mit e=numeric;e(n)in 5 - Instanzen aufgrund JDL , und 17 weiteren Bytes aufgrund JDL .

Update 2. Da es sich bei dem Sandhaufen um einen Abelschen Sandhaufen handelt, kann er mit einem Stapel gewünschter Höhe beginnen. Daher habe ich die redundante Schleife entfernt und die Produktivität erheblich gesteigert!

Andreï Kostyrka
quelle
1
Ich verstehe Ihren Standpunkt zu den zusätzlichen Spalten- und Zeilenindizes, die Sie ausgeben, aber ich denke, ich möchte die Ausgabe darauf beschränken, nur "die Antwort" zu sein, und nicht mehr. Ich bin jedoch froh, dass Sie Bilder hinzugefügt haben.
Eric Tressler
1
Schöne Antwort Andreï! Sie könnten aber definitiv ein paar Bytes Golf spielen, zum Beispiel vordefinieren rep(), vorausgesetzt, Sie verwenden es 6 Mal. Zweitens glaube ich nicht, dass Sie die arr.ind=TOption für die which()Funktion ausschreiben müssen. Einfach benutzen which(...,T).
Billywob
1
Es ist möglicherweise besser, dies zu definieren n=numericund zu verwenden, da n(k)es weniger Zeichen als gibt r(0,k). Die Bilder gefallen mir allerdings.
JDL
1
Ein weiterer Vorschlag: 1%*%0ist weniger Zeichen als array(0,c(1,1)). Auch das zweite Argument, u <- cbinddas nur 1 sein darf, cbindwird standardmäßig auf die Länge des ersten Arguments ausgedehnt.
JDL
1
@ GregMartin Behoben. Das tut mir leid; In meiner Muttersprache verwenden wir das Wort "Ich" und kümmern uns nie um das Geschlecht der betreffenden Person (wie "ein kleiner Schritt für einen Mann"). dennoch nenne ich manchmal in sehr seltenen Fällen einen Hund "sie" oder "er", während es "es" sein sollte, es sei denn, Sie sind der Besitzer und möchten das Geschlecht Ihres Anumals wirklich betonen ( trotz der Tatsache, dass es nicht so schwer ist, ein Männchen von einem Weibchen zu unterscheiden).
Andreï Kostyrka
13

MATL , 55 53 48 43 42 Bytes

Inspiriert von @flawrs Antwort .

Grafische Ausgabe :

0i:"Gto~+XytP*+t"t4=t1Y6Z+b+w~*]]tat3$)1YG

Probieren Sie es bei MATL Online! . Die Eingabe dauert ca. 10 Sekunden 30. Möglicherweise müssen Sie die Seite aktualisieren und erneut auf "Ausführen" klicken, wenn dies nicht funktioniert.

Hier ist ein Beispielergebnis für die Eingabe 100:

Bildbeschreibung hier eingeben

ASCII-Ausgabe (43 Byte) :

0i:"Gto~+XytP*+t"t4=t1Y6Z+b+w~*]]tat3$)48+c

Probieren Sie es online!

Erläuterung

0          % Push a 0. This is the initial array. Will be resized in first iteration
i:         % Take input n. Generate range [1 2 ... n]
"          % For each, i.e. repeat n times
  Gto~+    %   Push input and add negate parity. This "rounds up" n to odd number
           %   m = n or n+1
  Xy       %   Identity matrix with that size
  tP*      %   Multiply element-wise by vertically flipped copy. This produces a
           %   matrix with a 1 in the center and the rest entries equal to 0
  +        %   Add to previous array. This updates the sandpile array
  t        %   Duplicate
  "        %   For each column (i.e. repeat m times)
    t4=    %     Duplicate. Compare with 4 element-wise. This gives a 2D mask that
           %     contains 1 for entries of the sandpile array that equal 4, and 0
           %     for the rest
    t      %     Duplicate
    1Y6    %     Predefined literal: [0 1 0; 1 0 1; 0 1 0]
    Z+     %     2D convolution, maintaining size
    b      %     Bubble up to bring sandpile array to top
    +      %     Element-wise addition. This adds 1 to the neighbours of a 4
    w      %     Swap to bring copy of mask to top
    ~*     %     Multiply bu negated mask. This removes all previous 4
  ]        %  End
]          % End
t          % Duplicate the updated sandpile array
a          % 1D mask that contains 1 for columns that contain a 1. This will be
           % used as a logical index to select columns
t          % Duplicate. This will be used as logical index to select rows (this
           % can be done because of symmetry)
3$)        % Keep only those rows and columns. This trims the outer zeros in the
           % sandpile array
1YG        % Display as scaled image
Luis Mendo
quelle
3
Ich bin neidisch auf 1Y6.
Fehler
1
@flawr Aber Ihr ~mod(spiral(3),2)ist viel schlauer :-)
Luis Mendo
11

Matlab, 160 156 148 Bytes

n=input('');z=zeros(3*n);z(n+1,n+1)=n;for k=1:n;x=z>3;z=z+conv2(+x,1-mod(spiral(3),2),'s');z(x)=z(x)-4;end;v=find(sum(z));z=z(v,v);[z+48-(z<1)*2,'']

Zuerst wird eine viel zu große Matrix erstellt, mit der nirgendwo in der Mitte. Dann wird die Kaskadierung mit einer sehr praktischen 2D-Faltung berechnet. Am Ende wird der Überschuss abgeschnitten und das Ganze in einen String umgewandelt.

Beispielausgabe für t=100

...121...
..32.23..
.3.323.3.
123.3.321
2.23.32.2
123.3.321
.3.323.3.
..32.23..
...121...

Wie immer:

Faltung ist der Schlüssel zum Erfolg.

fehlerhaft
quelle
v=any(z)statt v=find(sum(z))(ich benutze das in meiner Antwort). Auch 2*~zanstelle von(z<1)*2
Luis Mendo
Mein Computer fror bei der Eingabe ein n=500... Es wurde seit n=400einigen Sekunden verarbeitet. Mache ich etwas falsch?
Andreï Kostyrka
@ AndreïKostyrka Es funktioniert für mich (Matlab R2015b)
Luis Mendo
1
@ AndreïKostyrka Für eine Eingabe ngeneriert dieses Programm eine 3*n x 3*nMatrix, so dass es etwa 9*n^2Zahlen speichern muss . Außerdem ist es völlig ineffizient, weil wir auch eine völlig unnötige lange Iteration von 1 bis n haben. Aber andererseits ist das Code-Golf , ein Programm effizient zu machen, ist eine andere Sache.
Fehler
@ AndreïKostyrka Sie können die Speichereffizienz erhöhen, indem Sie spärliche Matrizen (zweite Zeile:) verwenden z=sparse(zeros(2*n+1))und die for-Schleife auf ändern while any(z(:)>3). Dann können Sie vielleicht auch die Faltungskern berechnen nur einmal: kern = 1-mod(spiral(3),2).
Fehler
9

Python 2, 195 +1 +24 = 220 217

from pylab import*
ifrom scipy.signal import convolve2d as c
k=(arange(9)%2).reshape(3,3)
def f(n):g=zeros((n,n),int);g[n/2,n/2]=n;exec"g=c(g/4,k,'same')+g%4;"*n;return g[any(g,0)].T[any(g,0)]

Ausgabe für n = 16

array([[0, 0, 1, 0, 0],
       [0, 2, 1, 2, 0],
       [1, 1, 0, 1, 1],
       [0, 2, 1, 2, 0],
       [0, 0, 1, 0, 0]])

Es gibt eine Menge unnötiger Auffüllungen und Iterationen, wenn man nals "ausreichend" -Obergrenze verwendet, aber n = 200 ist immer noch in einer Sekunde abgeschlossen und n = 500 in ungefähr 12 Sekunden

ungolfed

from pylab import*
from scipy.signal import convolve2d as c
k=array([0,1,0],
        [1,0,1],
        [0,1,0])
def f(n):
  g=zeros((n,n))                 # big grid of zeros, way bigger than necessary
  g[n/2,n/2]=n                   # put n grains in the middle
  exec"g=c(g/4,k,'same')+g%4;"*n # leave places with <4 grains as is, convolve the rest with the kernel k, repeat until convergence (and then some more)
  return g[any(g,0)].T[any(g,0)] # removes surrounding 0-rows and columns

Ersetzen return xdurch imshow(x)Fügt ein Zeichen hinzu und gibt ein hässliches interpoliertes Bild aus. Durch Hinzufügen imshow(x,'gray',None,1,'nearest')wird die unscharfe Interpolation entfernt, wodurch die Ausgabe den Spezifikationen entspricht

n = 100

DenDenDo
quelle
Ich erhalte die folgende Fehlermeldung , wenn ich Ihren Code ausführen: ImportError: No module named convolve2d. Ändern, import scipy.signal.convolve2d as cum from scipy.signal import convolve2d as cdas Problem zu beheben. Ich verwende scipy Version 0.16.1. Benötige ich eine ältere oder neuere Version? Oder ist das Problem etwas anderes?
Andrew Epstein
komisch, jetzt wo du erwähnst, dass es auch bei mir nicht mehr funktioniert. Ich habe es wahrscheinlich gleich beim ersten Mal im interaktiven Modus richtig gemacht, es dann gekürzt und den Fehler ignoriert, aber die Funktion blieb im Speicher
DenDenDo
6

Perl, 157 147 Bytes

Beinhaltet +1 für -p

Mit der Zählung auf STDIN ausführen, die Karte mit 0123auf STDOUT drucken:

sandpile.pl <<< 16

sandpile.pl:

#!/usr/bin/perl -p
map{++substr$_,y///c/2-1,1;/4
/?$.+=s%^|\z%0 x$..$/%eg+!s/\b/0/g:s^.^$&%4+grep{3<substr$\,0|$_+"@+",1}-$.-2,-2,0,$.^eg while/[4-7]/}($\="0
")x$_}{
Tonne Hospel
quelle
5

Python 3 2, 418 385 362 342 330 Bytes

w='[(i,j)for i in r(n)for j in r(n)if a[i][j]>3]'
def f(z):
 a,x,r=[[z]],0,range
 for _ in[0]*z:
  n=len(a);v=eval(w)
  if[1for b,c in v if(b==0)+(c==0)]:n+=2;a=[[0]*n]+[[0]+a[i]+[0]for i in r(n-2)]+[[0]*n];x+=1;v=eval(w)
  for c,d in v:exec'a[c+%s][d+%s]+=1;'*4%(-1,0,1,0,0,-1,0,1);a[c][d]-=4
 for i in a:print''.join(map(str,i))

Edit: 6 Bytes gespart dank @ Qwerp-Derp

Wir danken @ Andreï Kostyrka für die direkte Übersetzung seines R-Codes in Python.

Andrew Epstein
quelle
Ich denke, Sie können die Zuweisung von a,x,rin die Funktionsargumente verschieben.
Loovjo
1
Ich habe Ihren Code um ein paar Bytes heruntergespielt ... es ist nicht viel, aber es muss reichen. Stört es Sie, wenn ich Ihre Antwort bearbeite und die Version von Python auf Python 2 ändere?
Clismique
@ Qwerp-Derp: Fühl dich frei! Ich würde gerne sehen, was du getan hast.
Andrew Epstein
3

JavaScript, 418 416 406 400 393 Bytes

Erstellt eine anonyme Funktion, die die Ausgabe auf der Konsole anzeigt.

var f =
    t=>{a=(q,w)=>Math.max(q,w);c=_=>{x=a(p[0],x);y=a(p[1],y);m[p]=(g(p)+1)%4;if(!m[p]){s.push([p[0],p[1]]);}};x=y=0,m={};g=k=>{v=m[k];return!v?0:v;};m[o=[0,0]]=1;s=[];while(--t){m[o]=(m[o]+1)%4;if(!m[o]){s.push(o);}while(s.length){p=s.pop();p[0]++;c();p[0]-=2;c();p[0]++;p[1]++;c();p[1]-=2;c();p[1]++;}}s='';for(i=-x;i<=x;i++){for(j=-y;j<=y;j++){v=g([i,j]);s+=v==0?'.':v;}s+='\n';}console.log(s);}
<input id="i" type="number"><input type="button" value="Run" onclick="var v = +document.getElementById('i').value; if (v>0) f(v)">

hetzi
quelle
1
Warnung: Ich habe 'run' ohne Eingabe gedrückt und mein Bildschirm ist abgestürzt (Endlosschleife). Sei nicht so albern wie ich.
roberrrt-s
1
@Roberrrt Ich habe meine Antwort aktualisiert, um dies zu verhindern.
Hetzi
3

Nim, 294 Zeichen

import os,math,sequtils,strutils
var
 z=parseFloat paramStr 1
 y=z.sqrt.toInt+1
 w=y/%2
 b=y.newSeqWith newSeq[int] y
 x=0
proc d(r,c:int)=
 b[r][c]+=1;if b[r][c]>3:b[r][c]=0;d r-1,c;d r,c+1;d r+1,c;d r,c-1
for i in 1..z.toInt:d w,w
while b[w][x]<1:x+=1
for r in b[x..< ^x]:echo join r[x..< ^x]

Kompilieren und ausführen:

nim c -r sandbox.nim 1000

Anmerkungen:

  1. Ich konnte eine kürzere Version entwickeln, die eine feste Tabellengröße verwendet, diese habe ich jedoch zugunsten der dynamischen herausgeschnitten.
  2. Sobald die Sandbox berechnet ist, xwird als Anzahl der Nullspalten am Anfang der mittleren Zeile gerechnet.
  3. Für die Anzeige wird die Tabelle durch Ausschließen von xZeilen und Spalten von jedem Ende getrennt.

Performance

nim c --stackTrace:off --lineTrace:off --threads:off \ 
      --checks:off --opt:speed sandbox.nim

time ./sandbox   10000       0.053s
time ./sandbox   20000       0.172s
time ./sandbox   30000       0.392s
time ./sandbox   40000       0.670s
time ./sandbox  100000       4.421s
time ./sandbox 1000000    6m59.047s
Danny Kirchmeier
quelle
3

Scala, 274 Bytes

val t=args(0).toInt
val s=(Math.sqrt(t)+1).toInt
val (a,c)=(Array.ofDim[Int](s,s),s/2)
(1 to t).map{_=> ?(c,c)}
println(a.map{_.mkString}.mkString("\n"))
def?(b:Int,c:Int):Unit={
a(b)(c)+=1
if(a(b)(c)<4)return
a(b)(c)=0
?(b+1,c)
?(b-1,c)
?(b,c+1)
?(b,c-1)
}

Verwendungszweck:

scala sandpile.scala <iterations>

Ich denke, es gibt nicht viel zu erklären. Im Grunde fügt es nur ein Sandkorn in die Mitte. Dann wird geprüft, ob es größer als 4 ist. Wenn dies der Fall ist, wird überprüft, ob alle Nachbarn, die größer als 4 sind, übergelaufen sind, usw. Es geht recht schnell.

Performance:

  • t = 10000 72 ms
  • t = 20000 167 ms
  • t = 30000 419 ms
  • t = 40000 659 ms
  • t = 100000 3413 ms
  • t = 1000000 ungefähr 6 Minuten
AmazingDreams
quelle
Mein Programm schlägt vor, dass der Sandhaufen zentriert bei (0,0) zuerst bei t = 1552 einen Radius von 15 trifft. Das würde ein 31x31-Array zum Speichern erfordern (Koordinaten -15 bis 15 einschließlich). Sind Sie sicher, dass dies durch t = 5000 korrekt ist?
Eric Tressler
Ich bin mir nicht sicher, ob das richtig ist, obwohl ich denke, ich habe die richtige Logik? Ich bekomme einen Array-Index außerhalb der Grenzen Ausnahme auf t> 5593
AmazingDreams
Wenn ich inkrementiere und dann sofort prüfe, ob etwas verschüttet wurde, verliert es bei t = 1552 seine Grenzen. Ich würde sagen, das ist die richtige Implementierung. Ich habe den Code aktualisiert.
AmazingDreams
Ihre Leistung kann nur durch direkte Array-Manipulation in C oder Fortran mit Compiler-Optimierung übertroffen werden. Ich beneide dich.
Andreï Kostyrka
@ AndreïKostyrka, ja, hier leuchtet die Scala! Meine Ausgabe entspricht jedoch nicht den Spezifikationen, sodass ich daran arbeiten muss
AmazingDreams,
2

J, 76 Bytes

p=:0,.~0,.0,~0,]
p`(4&|+3 3([:+/@,*&(_3]\2|i.9));._3[:<.4%~p)@.([:*/4>{.)^:_

Ich definiere ein Verb, pdas einen Rand von Nullen um die Eingabe auffüllt. Das Hauptverb nimmt ein Array als Eingabe. Anschließend wird in der ersten Zeile nach Sandhaufen gesucht, die 4 oder mehr Körner enthalten. Wenn dies der Fall ist, wird dasselbe Array mit Ausnahme von padded using ausgegeben. pAndernfalls wird eine 2d-Faltung durchgeführt, um fallende Körner zu simulieren. Das Hauptverb wird mit dem Operator power bis zur Konvergenz wiederholt ^:_.

Verwendungszweck

   p =: 0,.~0,.0,~0,]
   f =: p`(4&|+3 3([:+/@,*&(_3]\2|i.9));._3[:<.4%~p)@.([:*/4>{.)^:_
   f 15
0 3 0
3 3 3
0 3 0
   f 50
0 0 0 1 0 0 0
0 0 3 1 3 0 0
0 3 2 2 2 3 0
1 1 2 2 2 1 1
0 3 2 2 2 3 0
0 0 3 1 3 0 0
0 0 0 1 0 0 0
   timex 'r =: f 50000'
46.3472
   load 'viewmat'
   ((256#.3&#)"0<.255*4%~i._4) viewmat r

Es dauert ungefähr 46 Sekunden, um das Ergebnis für n = 50000 zu berechnen , und das Ergebnis kann unter Verwendung des viewmatAddons mit einem monochromen Farbschema angezeigt werden .

Zahl

Meilen
quelle
2

C 229 (mit vielen Warnungen)

G[99][99],x,y,a=99,b=99,c,d;S(x,y){if(++G[y][x]>3)G[y][x]=0,S(x+1,y),S(x-1,y),S(x,y+1),S(x,y-1);a=x<a?x:a;b=y<b?y:b;c=x>c?x:c;d=y>d?y:d;}F(t){for(;t--;)S(49,49);for(y=b;y<=d;y++){for(x=a;x<=c;x++)printf("%d ",G[y][x]);puts("");}}

/* call it like this */
main(_,v)char**v;{F(atoi(v[1]));}
Jerry Jeremiah
quelle
Okay, ich gebe auf: warum ist dein Array 99 mal 98?
Eric Tressler
@EricTressler Wie habe ich das beim Testen nicht gefunden ?!
Jerry Jeremiah
1

PHP, 213 Bytes

function d($x,$y){global$p,$m;$m=max($m,$x);$q=&$p[$y][$x];if(++$q>3){$q=0;d($x+1,$y);d($x-1,$y);d($x,$y+1);d($x,$y-1);}}while($argv[1]--)d(0,0);for($y=-$m-1;$y++<$m;print"\n")for($x=-$m;$x<=$m;)echo+$p[$y][$x++];

erstellt rekursiv den Stapel in $p, wobei die Größe in gespeichert wird $m; Dann wird mit verschachtelten Schleifen gedruckt.
Laufen Sie mit -r.

Titus
quelle