Bangunlah tumpukan pasir

59

Sebuah sandpile abelian , untuk tujuan kita, adalah jaringan yang tak terbatas dengan koordinat bilangan bulat, awalnya kosong pasir. Setelah setiap detik, sebutir pasir ditempatkan pada (0,0). Setiap kali sel grid memiliki 4 atau lebih butir pasir, ia menumpahkan satu butir pasir ke masing-masing empat tetangganya secara bersamaan. Tetangga (x, y) adalah (x-1, y), (x + 1, y), (x, y-1), dan (x, y + 1).

Ketika sebuah sel tumpah, itu bisa menyebabkan tetangganya tumpah. Beberapa fakta:

  • Kaskade ini pada akhirnya akan berhenti.
  • Urutan di mana sel-sel tumpah tidak relevan; hasilnya akan sama.

Contoh

Setelah 3 detik, kotak terlihat seperti

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

Setelah 4 detik:

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

Setelah 15 detik:

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

Dan setelah 16 detik:

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

Tantangan

Dalam sesedikit mungkin byte, tulislah fungsi yang mengambil t bilangan bulat positif tunggal dan menghasilkan gambar tumpukan pasir setelah t detik.

Memasukkan

Satu bilangan bulat positif t , dalam format apa pun yang Anda pilih.

Keluaran

Gambar tumpukan pasir setelah t detik, menggunakan karakter

 . 1 2 3

Sunting: Gunakan empat karakter berbeda yang Anda suka, atau buat gambar. Jika Anda tidak menggunakan ".123" atau "0123", tentukan dalam jawaban Anda apa yang ditandai oleh karakter.

Tidak seperti dalam contoh, output Anda harus mengandung jumlah minimum baris dan kolom yang diperlukan untuk menunjukkan bagian nol dari sandpile.

Artinya, untuk input 3, output harus

 3

Untuk 4, output seharusnya

 .1.
 1.1
 .1.

Mencetak gol

Berlaku standar skor golf.

Aturan

Tidak ada fungsi bahasa atau pustaka yang sudah tahu apa sandpile diperbolehkan.

Sunting: Bagian output telah diedit, batasan set karakter telah sepenuhnya diangkat. Gunakan empat karakter atau warna berbeda yang Anda suka.

Eric Tressler
sumber
2
Dapat masukan t menjadi 0? Apa ouput itu?
Luis Mendo
1
Apakah benar karena pada waktu yang ditentukan banyak kaskade dapat terjadi secara berurutan? Jadi dalam catatan waktu itu kaskade terus terjadi sampai setiap sel lagi 3 atau kurang?
flawr
2
@ flawr: Ya, itu benar. Lihatlah perbedaan antara t = 15 dan t = 16.
El'endia Starman
@LuisMendo Input ditentukan sebagai t positif , jadi nol bukan input yang valid.
Eric Tressler
1
Apakah BENAR-BENAR perlu dimiliki .sel kosong? Bisakah kita memiliki 0sel kosong yang valid?
Andreï Kostyrka

Jawaban:

56

R, 378 343 297 291 byte

Seperti biasa, pengguna memasok inputnya melalui scan()(saya sudah menggunakan variabel t, jadi mari kita ambil zsebagai gantinya), jadi baris kedua harus diluncurkan secara terpisah, dan kemudian sisanya:

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

Menghasilkan array yang berisi nilai-nilai apada tgenerasi ke-0 (0, 1, 2 atau 3).

Kasus uji:

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

Ini membantu kita bahwa hal ini simetris baik secara vertikal maupun horizontal, yang berarti bahwa titik paling kiri mendapat ketinggian 4, ini berarti bahwa titik paling atas, paling kanan dan terendah juga 4.

Oh, dan apakah saya mengatakan bahwa Anda dapat membuat visualisasi yang indah?

Setelah 1000 tetes:

Tumpukan abelian setelah 1000 langkah

Setelah 50000 tetes (≈4 detik):

Tumpukan abelian setelah 50000 langkah

Setelah 333333 tetes (≈15 menit):

Tumpukan abelian setelah 100000 langkah

Anda bisa menggambarnya juga!

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

Hal ini membutuhkan waktu 4 detik untuk 10.000 iterasi tetapi melambat jauh untuk ukuran array yang lebih besar (misalnya beberapa menit untuk 100000 iterasi). Inilah sebabnya mengapa ia menjadi sangat lambat (saya memperkirakan tingkat pertumbuhan seperti pada Tingkat pertumbuhandan memperoleh τ (i) ≈689 · i ^ 1.08, jadi waktu rata-rata per satu butir tambahan sampai seluruh tumpukan pasir mengendap setelah ilangkah sedikit lebih besar dari satu) , dan total waktu sebagai fungsi dari jumlah butiran tumbuh sedikit lebih lambat daripada kuadratik (T (i) .00.028 * i ^ 1,74):

Rata-rata iterasi hingga tumpukan mengendap

Perkiraan waktu perhitungan

Dan sekarang dengan penjelasan lengkap:

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

Ini adalah pertama kalinya dalam hidup saya ketika menumbuhkan objek (seperti a <- c(a, 1)) bekerja jauh lebih cepat daripada mengalokasikan matriks kosong yang besar untuk nilai-nilai dan mengisinya secara bertahap dengan satu ton nol yang tidak digunakan.

Memperbarui. Golfed 18 byte dengan menghilangkan arr.inddalam whichkarena Billywob dan mengganti rep(0,n)dengan e=numeric;e(n)di 5 kasus karena JDL , dan 17 byte lagi karena JDL .

Pembaruan 2. Karena tumpukan pasir adalah Abelian, itu mungkin dimulai dengan setumpuk ketinggian yang diinginkan, jadi saya menghapus loop berlebihan dan mendapatkan peningkatan besar dalam produktivitas!

Andreï Kostyrka
sumber
1
Saya mendapatkan poin Anda tentang kolom tambahan, indeks baris yang Anda hasilkan, tapi saya pikir saya ingin membatasi output hanya menjadi "jawabannya", dan tidak lebih. Saya senang Anda memasukkan gambar.
Eric Tressler
1
Jawaban yang bagus, Andreï! Anda pasti bisa bermain golf beberapa byte, misalnya rep(), pra-penetapan , mengingat Anda menggunakannya 6 kali. Kedua, saya rasa Anda tidak perlu menuliskan arr.ind=Topsi untuk which()fungsi tersebut. Cukup gunakan which(...,T).
Billywob
1
Mungkin golfier untuk mendefinisikan n=numericdan menggunakannya, karena n(k)karakter lebih sedikit daripada r(0,k). Saya suka gambarnya.
JDL
1
Saran lain: 1%*%0lebih sedikit karakter daripada array(0,c(1,1)). Argumen kedua yang u <- cbindbisa saja 1, cbindakan memperpanjang ke panjang argumen pertama secara default.
JDL
1
@GregMartin Memperbaiki ini. Maaf untuk itu; dalam bahasa pertama saya, kami menggunakan kata "diri" dan tidak pernah peduli dengan jenis kelamin orang yang bersangkutan (seperti "satu langkah kecil untuk pria"); masih, kadang-kadang, pada kesempatan yang sangat jarang, saya memanggil anjing "dia" atau "dia", sedangkan itu harus "itu", kecuali, seperti, Anda adalah pemilik dan Anda benar - benar ingin menekankan jenis kelamin anumal Anda ( meskipun fakta bahwa mengatakan laki-laki dari perempuan tidak sulit).
Andreï Kostyrka
13

MATL , 55 53 48 43 42 byte

Terinspirasi oleh jawaban @ flawr .

Output grafis :

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

Cobalah di MATL Online! . Diperlukan sekitar 10 detik untuk input 30. Anda mungkin perlu me-refresh halaman dan tekan "Run" lagi jika itu tidak berhasil.

Berikut ini contoh hasil untuk input 100:

masukkan deskripsi gambar di sini

Output ASCII (43 byte) :

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

Cobalah online!

Penjelasan

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
sumber
3
Saya cemburu 1Y6.
flawr
1
@ flawr Tapi Anda ~mod(spiral(3),2)jauh lebih pintar :-)
Luis Mendo
11

Matlab, 160 156 148 byte

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,'']

Pertama cara matriks terlalu besar dibuat, dengan ndi tengah suatu tempat. Kemudian cascading dihitung dengan konvolusi 2d yang sangat nyaman. Pada akhirnya kelebihan dipangkas dan semuanya dikonversi menjadi string.

Contoh output untuk t=100

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

Seperti biasa:

Konvolusi adalah kunci kesuksesan.

cacat
sumber
v=any(z)alih-alih v=find(sum(z))(saya menggunakan itu dalam jawaban saya). Juga, 2*~zbukannya(z<1)*2
Luis Mendo
Komputer saya membeku saat input n=500... Itu telah diproses n=400selama beberapa detik. Apakah saya melakukan sesuatu yang salah?
Andreï Kostyrka
@ AndreïKostyrka Berhasil untuk saya (Matlab R2015b)
Luis Mendo
1
@ AndreïKostyrka Untuk input dari nprogram ini menghasilkan sebuah 3*n x 3*nmatriks, sehingga perlu menyimpan tentang 9*n^2angka. Juga sangat tidak efisien, karena kami juga memiliki iterasi panjang yang sama sekali tidak perlu dari 1 hingga n. Tetapi sekali lagi ini adalah kode-golf , membuat program yang efisien adalah secangkir teh yang berbeda.
flawr
@ AndreïKostyrka Anda dapat membuatnya lebih hemat memori dengan menggunakan matriks jarang (baris kedua:) z=sparse(zeros(2*n+1))dan mengubah for loop menjadi while any(z(:)>3). Kemudian Anda juga bisa mungkin menghitung kernel konvolusi hanya sekali: kern = 1-mod(spiral(3),2).
flawr
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)]

output untuk 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]])

ada banyak padding dan iterasi yang tidak perlu, dengan menggunakan nsebagai batas atas "cukup baik", tetapi n = 200 masih selesai dalam detik dan n = 500 dalam waktu sekitar 12 detik

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

mengganti return xdengan imshow(x)menambahkan satu karakter dan menghasilkan gambar interpolasi jelek, menambahkan imshow(x,'gray',None,1,'nearest')menghilangkan interpolasi buram membawa output hingga spesifikasi

n = 100

DenDenDo
sumber
Saya mendapatkan error berikut ketika saya menjalankan kode Anda: ImportError: No module named convolve2d. Mengubah import scipy.signal.convolve2d as cuntuk from scipy.signal import convolve2d as cmenyelesaikan masalah. Saya menggunakan versi scipy 0.16.1, apakah saya memerlukan versi yang lebih lama atau lebih baru? Atau apakah masalahnya berbeda?
Andrew Epstein
aneh, sekarang Anda menyebutkan bahwa itu tidak berfungsi untuk saya lagi. Saya mungkin melakukannya dengan benar pertama kali dalam mode interaktif, kemudian memperpendeknya dan mengabaikan kesalahan, tetapi fungsinya tetap
tersimpan
6

Perl, 157 147 byte

Termasuk +1 untuk -p

Jalankan dengan hitungan pada STDIN, cetak peta menggunakan 0123ke STDOUT:

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$_}{
Ton Hospel
sumber
5

Python 3 2, 418 385 362 342 330 byte

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: disimpan 6 byte berkat @ Qwerp-Derp

Semua pujian untuk @ Andreï Kostyrka, karena ini adalah terjemahan langsung dari kode R-nya ke Python.

Andrew Epstein
sumber
Saya pikir Anda dapat memindahkan penugasan a,x,rke argumen fungsi.
Loovjo
1
Saya telah menurunkan kode Anda dengan beberapa byte ... tidak banyak, tetapi harus dilakukan. Apakah Anda keberatan jika saya mengedit jawaban Anda dan jika saya mengubah versi Python ke Python 2?
clismique
@ Qwerp-Derp: Jangan ragu! Saya ingin melihat apa yang telah Anda lakukan.
Andrew Epstein
3

JavaScript, 418 416 406 400 393 byte

Menciptakan fungsi anonim yang menampilkan output di konsol.

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
sumber
1
Peringatan: Saya menekan 'run' tanpa input, dan layar saya mogok (infinite loop). Jangan konyol seperti saya.
roberrrt-s
1
@ Robert Saya memperbarui jawaban saya untuk mencegah hal ini.
hetzi
3

Nim, 294 karakter

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]

Kompilasi dan Jalankan:

nim c -r sandbox.nim 1000

Catatan:

  1. Saya dapat menghasilkan versi yang lebih pendek yang menggunakan ukuran tabel tetap, tetapi saya mengeditnya demi yang dinamis.
  2. Setelah kotak pasir dihitung, xdihitung sebagai jumlah kolom nol pada awal baris tengah.
  3. Untuk tampilan, tabel diiris dengan mengecualikan xbaris dan kolom dari masing-masing ujung.

Performa

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
sumber
3

Scala, 274 byte

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)
}

Pemakaian:

scala sandpile.scala <iterations>

Saya rasa tidak banyak yang bisa dijelaskan tentang ini. Pada dasarnya itu hanya menambahkan satu butir pasir ke tengah. Kemudian periksa apakah lebih besar dari 4, jika demikian itu akan tumpah dan memeriksa semua tetangga lebih besar dari 4, tumpah, dll. Ini cukup cepat.

Kinerja:

  • t = 10000 72ms
  • t = 20000 167ms
  • t = 30000 419ms
  • t = 40000 659ms
  • t = 100000 3413ms
  • t = 1000000 sekitar 6 menit
AmazingDreams
sumber
Program saya menyarankan bahwa, berpusat pada (0,0), tumpukan pasir pertama kali mencapai jari-jari 15 pada t = 1552. Itu akan membutuhkan array 31x31 untuk menyimpan (koordinat -15 hingga 15 inklusif). Apakah Anda yakin ini benar melalui t = 5000?
Eric Tressler
Saya tidak yakin ini benar, meskipun saya pikir saya mendapatkan logika yang benar? Saya mendapatkan indeks array di luar batas pada t>
5593
Ketika saya menambah dan kemudian segera memeriksa tumpahan itu keluar batas pada t = 1552. Saya akan mengatakan itu adalah implementasi yang benar. Saya memperbarui kode.
AmazingDreams
Kinerja Anda dapat dikalahkan hanya dengan manipulasi array langsung di C atau Fortran dengan optimisasi kompiler. Saya iri padamu.
Andreï Kostyrka
@ Andreï Kostyrka, ya, ini adalah di mana scala bersinar! Output saya tidak sesuai dengan spesifikasi, jadi saya harus mengerjakannya
AmazingDreams
2

J, 76 byte

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

Saya mendefinisikan kata kerja pyang melapisi batas nol di sekitar input. Kata kerja utama mengambil array sebagai input. Kemudian memeriksa baris pertama untuk setiap tumpukan pasir yang berisi 4 atau lebih butir. Jika ada, itu menghasilkan array yang sama kecuali menggunakan empuk p, dan jika tidak melakukan konvolusi 2d untuk mensimulasikan jatuh butir. Kata kerja utama diulang sampai konvergensi menggunakan operator daya ^:_.

Pemakaian

   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

Diperlukan waktu sekitar 46 detik untuk menghitung hasil untuk n = 50000, dan hasilnya dapat ditampilkan menggunakan viewmataddon dengan skema warna monokrom.

angka

mil
sumber
2

C 229 (dengan banyak peringatan)

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
sumber
Oke, saya menyerah: mengapa array Anda 99 oleh 98?
Eric Tressler
@EricTressler Bagaimana saya tidak menemukan itu dalam pengujian ?!
Jerry Jeremiah
1

PHP, 213 byte

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++];

secara rekursif membuat tumpukan $p, mengingat ukurannya $m; kemudian mencetak dengan loop bersarang.
Jalankan dengan -r.

Titus
sumber