Xây dựng một hố cát


59

Một hố cát abelian , cho mục đích của chúng tôi, là một lưới vô hạn với tọa độ nguyên, ban đầu không có cát. Sau mỗi giây, một hạt cát được đặt ở (0,0). Bất cứ khi nào một tế bào lưới có 4 hạt cát trở lên, nó sẽ đổ một hạt cát cho bốn hạt lân cận của nó cùng một lúc. Các hàng xóm của (x, y) là (x - 1, y), (x + 1, y), (x, y - 1) và (x, y + 1).

Khi một tế bào tràn ra, nó có thể khiến hàng xóm của nó tràn ra. Một số sự thật:

  • Dòng thác này cuối cùng sẽ dừng lại.
  • Thứ tự mà các tế bào tràn ra là không liên quan; kết quả sẽ giống nhau

Thí dụ

Sau 3 giây, lưới trông như

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

Sau 4 giây:

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

Sau 15 giây:

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

Và sau 16 giây:

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

Các thách thức

Trong khi vài byte càng tốt, hãy viết một hàm mang theo một đơn dương nguyên t và kết quả đầu ra một hình ảnh của sandpile sau t giây.

Đầu vào

Một đơn dương nguyên t , ở định dạng bất kỳ mà bạn chọn.

Đầu ra

Một hình ảnh của hố cát sau t giây, sử dụng các ký tự

 . 1 2 3

Chỉnh sửa: Sử dụng bất kỳ bốn ký tự riêng biệt nào bạn thích hoặc vẽ một hình ảnh. Nếu bạn không sử dụng ".123" hoặc "0123", hãy xác định trong câu trả lời của bạn những gì các ký tự biểu thị.

Không giống như trong các ví dụ, đầu ra của bạn phải chứa số lượng hàng và cột tối thiểu cần thiết để hiển thị phần khác không của hố cát.

Đó là, đối với đầu vào 3, đầu ra phải là

 3

Đối với 4, đầu ra phải là

 .1.
 1.1
 .1.

Chấm điểm

Điểm golf tiêu chuẩn được áp dụng.

Quy tắc

Không có chức năng ngôn ngữ hoặc thư viện nào đã biết những gì một hố cát được cho phép.

Chỉnh sửa: Phần đầu ra đã được chỉnh sửa, hạn chế bộ ký tự đã được gỡ bỏ hoàn toàn. Sử dụng bất kỳ bốn ký tự hoặc màu sắc riêng biệt mà bạn thích.


2
Đầu vào t có thể được 0không? Sau đó là gì?
Luis Mendo

1
Có đúng không trong một dấu thời gian nhất định, nhiều tầng có thể diễn ra liên tiếp? Vì vậy, trong dấu thời gian đó, các thác tiếp tục xảy ra cho đến khi mỗi ô lại là 3 hoặc ít hơn?
flawr

2
@flawr: Vâng, điều đó sẽ đúng. Nhìn vào sự khác biệt giữa t = 15 và t = 16.
El'endia Starman

@LuisMendo Đầu vào được chỉ định là dương t , vì vậy số 0 không phải là đầu vào hợp lệ.
Eric Tressler

1
Có thực sự cần thiết phải có .cho các ô trống? Chúng ta có thể có 0một ô trống hợp lệ không?
Andreï Kostyrka

Câu trả lời:


56

R, 378 343 297 291 byte

Như thường lệ, người dùng cung cấp đầu vào của anh ấy / cô ấy thông qua scan()(tôi đã sử dụng biến t, vì vậy chúng ta hãy zthay thế), vì vậy dòng thứ hai sẽ được khởi chạy riêng, và sau đó là phần còn lại:

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

Xuất ra một mảng có chứa các giá trị atthế hệ thứ (0, 1, 2 hoặc 3).

Các trường hợp thử nghiệm:

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

Nó giúp chúng ta rằng vật này đối xứng cả theo chiều dọc và chiều ngang, có nghĩa là điểm ngoài cùng bên trái có chiều cao là 4, điều này có nghĩa là điểm trên cùng, ngoài cùng và thấp nhất cũng là 4.

Oh, và tôi đã nói rằng bạn có thể tạo ra hình ảnh đẹp?

Sau 1000 giọt:

Đồi cát Abelian sau 1000 bước

Sau 50000 giọt (≈4 giây):

Đồi cát Abelian sau 50000 bước

Sau 333333 giọt (≈15 phút):

Đồi cát Abelian sau 100000 bước

Bạn cũng có thể vẽ nó!

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

Điều này mất 4 giây cho 10000 lần lặp nhưng chậm lại đáng kể đối với kích thước mảng lớn hơn (ví dụ: vài phút cho 100000 lần lặp). Đây là lý do tại sao nó trở nên chậm chạp (tôi ước tính tốc độ tăng trưởng như trong Tỉ lệ tăng trưởngvà thu được (i) ≈689 · i ^ 1.08, vì vậy thời gian trung bình trên một hạt bổ sung cho đến khi toàn bộ hạt cát lắng xuống sau ibước thứ ba lớn hơn một chút) và tổng thời gian là một hàm của số lượng hạt tăng chậm hơn một chút so với phương trình bậc hai (T (i) 0.028 * i ^ 1.74):

Lặp lại trung bình cho đến khi cọc lắng

Thời gian tính toán gần đúng

Và bây giờ với một lời giải thích đầy đủ:

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

Đây là lần đầu tiên trong đời, khi các vật thể phát triển (như a <- c(a, 1)) hoạt động nhanh hơn nhiều so với việc phân bổ trước một ma trận trống lớn cho các giá trị và lấp đầy nó dần dần với một tấn số không được sử dụng.

Cập nhật. Golfed 18 byte bằng cách loại bỏ arr.indtrong whichdo Billywob và thay thế rep(0,n)với e=numeric;e(n)5 trường hợp do JDL , và nhiều hơn nữa 17 byte do JDL .

Cập nhật 2. Vì sandpile là Abelian, nó có thể bắt đầu với một chồng chiều cao mong muốn, vì vậy tôi đã loại bỏ vòng lặp dư thừa và đạt được sự tăng năng suất rất lớn!


1
Tôi nhận được quan điểm của bạn về cột thêm, các chỉ số hàng mà bạn đang xuất, nhưng tôi nghĩ rằng tôi muốn hạn chế đầu ra chỉ là "câu trả lời", và không có gì nữa. Tôi rất vui vì bạn đã bao gồm hình ảnh, mặc dù.
Eric Tressler

1
Câu trả lời hay đấy Andreï! Bạn chắc chắn có thể chơi golf một vài byte, ví dụ rep(), xác định trước , cho rằng bạn sử dụng nó 6 lần. Thứ hai, tôi không nghĩ bạn cần viết ra arr.ind=Ttùy chọn cho which()hàm. Đơn giản chỉ cần sử dụng which(...,T).
Billywob

1
Nó có thể là golfier để xác định n=numericvà sử dụng điều đó thay vào đó, vì n(k)có ít ký tự hơn r(0,k). Tôi thích những hình ảnh mặc dù.
JDL

1
Một đề nghị khác: 1%*%0là ít ký tự hơn array(0,c(1,1)). Ngoài ra, đối số thứ hai u <- cbindchỉ có thể là 1, cbindsẽ mở rộng nó đến độ dài của đối số thứ nhất theo mặc định.
JDL

1
@GregMartin Đã sửa lỗi này. Xin lỗi vì điều đó; trong ngôn ngữ đầu tiên của tôi, chúng tôi sử dụng từ "Tự bản thân" và không bao giờ bận tâm về giới tính của người được hỏi (như một bước nhỏ cho một người đàn ông); đôi khi, đôi khi, đôi khi, tôi gọi một con chó là cô ấy, hay một chú chó, trong khi đó phải là con chó, trừ khi, giống như, bạn là chủ sở hữu và bạn thực sự muốn nhấn mạnh đến giới tính của bạn ( mặc dù thực tế rằng nói nam từ nữ không khó lắm).
Andreï Kostyrka

13

MATL , 55 53 48 43 42 byte

Lấy cảm hứng từ câu trả lời của @ flawr .

Đầu ra đồ họa :

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

Hãy thử nó tại MATL Online! . Mất khoảng 10 giây cho đầu vào 30. Bạn có thể cần làm mới trang và nhấn "Chạy" lại nếu nó không hoạt động.

Đây là một kết quả ví dụ cho đầu vào 100:

nhập mô tả hình ảnh ở đây

Đầu ra ASCII (43 byte) :

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

Hãy thử trực tuyến!

Giải trình

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

3
Tôi ghen tị với 1Y6.
flawr

1
@flawr Nhưng bạn ~mod(spiral(3),2)thông minh hơn nhiều :-)
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,'']

Đầu tiên một cách quá lớn ma trận được tạo ra, với nở giữa một nơi nào đó. Sau đó, tầng được tính toán với tích chập 2d rất thuận tiện. Cuối cùng, phần thừa được cắt bớt và toàn bộ điều được chuyển thành một chuỗi.

Ví dụ đầu ra cho t=100

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

Như mọi khi:

Thuyết phục là chìa khóa thành công.


v=any(z)thay vì v=find(sum(z))(tôi đang sử dụng nó trong câu trả lời của tôi). Ngoài ra, 2*~zthay vì(z<1)*2
Luis Mendo

Máy tính của tôi đóng băng khi nhập liệu n=500... Nó đã được xử lý n=400trong vài giây. Tôi có làm điều gì sai?
Andreï Kostyrka

@ AndreïKostyrka Nó hoạt động với tôi (Matlab R2015b)
Luis Mendo

1
@ AndreïKostyrka Đối với đầu vào của nchương trình này tạo ra một 3*n x 3*nma trận, vì vậy nó cần lưu trữ về các 9*n^2số. Ngoài ra, nó hoàn toàn không hiệu quả, bởi vì chúng tôi cũng có một lần lặp dài hoàn toàn không cần thiết từ 1 đến n. Nhưng một lần nữa, đây là môn đánh gôn , làm cho chương trình hiệu quả là một tách trà khác.
flawr

@ AndreïKostyrka Bạn có thể makie nó hiệu quả bộ nhớ hơn bằng cách sử dụng ma trận thưa thớt (dòng thứ hai z=sparse(zeros(2*n+1)):) và thay đổi vòng lặp for thành while any(z(:)>3). Sau đó, bạn cũng có thể tính toán hạt nhân chập chỉ một lần : 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)]

đầu ra cho 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]])

có RẤT NHIỀU phần đệm và lặp lại không cần thiết, bằng cách sử dụng nnhư một giới hạn trên "đủ tốt", nhưng n = 200 vẫn hoàn thành trong một giây và n = 500 trong khoảng 12 giây

vô dụng

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

thay thế return xbằng cách imshow(x)thêm một ký tự và xuất ra một hình ảnh nội suy xấu xí, thêm imshow(x,'gray',None,1,'nearest')loại bỏ nội suy mờ đưa đầu ra lên đến thông số kỹ thuật

n = 100


Tôi gặp lỗi sau khi chạy mã của bạn : ImportError: No module named convolve2d. Thay đổi import scipy.signal.convolve2d as cđể from scipy.signal import convolve2d as cgiải quyết vấn đề. Tôi đang sử dụng phiên bản scipy 0.16.1, tôi có cần phiên bản cũ hơn hoặc mới hơn không? Hay là vấn đề gì khác?
Andrew Epstein

Thật kỳ lạ, bây giờ bạn đề cập rằng nó không còn hiệu quả với tôi nữa. Có lẽ tôi đã làm đúng ngay lần đầu tiên trong chế độ tương tác, sau đó rút ngắn và bỏ qua lỗi, nhưng chức năng vẫn nằm trong bộ nhớ
DenDenDo

6

Perl, 157 147 byte

Bao gồm +1 cho -p

Chạy với số đếm trên STDIN, in bản đồ bằng 0123STDOUT:

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$_}{

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

Chỉnh sửa: đã lưu 6 byte nhờ @ Qwerp-Derp

Tất cả tín dụng cho @ Andreï Kostyrka, vì đây là bản dịch trực tiếp mã R của anh ấy sang Python.


Tôi nghĩ rằng bạn có thể di chuyển sự phân công a,x,rvào các đối số chức năng.
Loovjo

1
Tôi đã giảm mã của bạn xuống một vài byte ... nó không nhiều, nhưng nó sẽ phải làm. Bạn có phiền nếu tôi chỉnh sửa câu trả lời của bạn và nếu tôi thay đổi phiên bản Python thành Python 2 không?
clismique

@ Qwerp-Derp: Hãy thoải mái! Tôi muốn xem những gì bạn đã làm.
Andrew Epstein

3

JavaScript, 418 416 406 400 393 byte

Tạo một chức năng ẩn danh hiển thị đầu ra trên bàn điều khiển.

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


1
Cảnh báo: Tôi nhấn 'chạy' mà không có đầu vào và màn hình của tôi bị hỏng (vòng lặp vô hạn). Đừng ngớ ngẩn như tôi.
roberrrt-s

1
@Roberrrt Tôi đã cập nhật câu trả lời của mình để ngăn chặn điều này.
hetzi

3

Nim, 294 ký tự

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]

Biên dịch và chạy:

nim c -r sandbox.nim 1000

Ghi chú:

  1. Tôi đã có thể đưa ra một phiên bản ngắn hơn sử dụng kích thước bảng cố định, nhưng tôi đã chỉnh sửa nó theo hướng có lợi cho phiên bản động.
  2. Khi hộp cát được tính toán, xđược tính bằng số cột không ở đầu hàng giữa.
  3. Để hiển thị, bảng được cắt xuống bằng cách loại trừ xcác hàng và cột từ mỗi đầu.

Hiệu suất

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

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

Sử dụng:

scala sandpile.scala <iterations>

Tôi không nghĩ có nhiều điều để giải thích về điều này. Về cơ bản nó chỉ cần thêm một hạt cát vào trung tâm. Sau đó kiểm tra xem nó có lớn hơn 4 không, nếu vậy nó sẽ tràn ra và kiểm tra tất cả các hàng xóm lớn hơn 4, tràn ra, v.v ... Nó khá nhanh.

Hiệu suất:

  • t = 10000 72ms
  • t = 20000 167ms
  • t = 30000 419ms
  • t = 40000 659ms
  • t = 100000 3413ms
  • t = 1000000 khoảng 6 phút

Chương trình của tôi gợi ý rằng, tập trung ở (0,0), lần đầu tiên sandpile đạt bán kính 15 tại t = 1552. Điều đó sẽ yêu cầu một mảng 31x31 để lưu trữ (bao gồm từ 15 đến 15). Bạn có chắc chắn điều này đúng qua t = 5000?
Eric Tressler

Tôi không chắc điều này là đúng, mặc dù tôi nghĩ rằng tôi có logic phải không? Tôi nhận được một chỉ số mảng trong giới hạn ngoại lệ trên t> 5593
AmazingDreams

Khi tôi tăng lên và ngay lập tức kiểm tra sự cố tràn, nó sẽ vượt ra khỏi giới hạn tại t = 1552. Tôi muốn nói rằng đó là cách thực hiện đúng. Tôi đã cập nhật mã.
AmazingDreams

Hiệu suất của bạn chỉ có thể bị đánh bại bằng cách thao tác mảng trực tiếp trong C hoặc Fortran với tối ưu hóa trình biên dịch. Tôi ghen tị với bạn.
Andreï Kostyrka

@ AndreïKostyrka, vâng, đây là nơi scala tỏa sáng! Đầu ra của tôi không phù hợp với thông số kỹ thuật mặc dù vậy tôi phải làm việc với điều đó
AmazingDreams

2

J, 76 byte

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

Tôi định nghĩa một động từ pđệm một đường viền số 0 xung quanh đầu vào. Động từ chính lấy một mảng làm đầu vào. Sau đó, nó kiểm tra hàng đầu tiên cho bất kỳ hố cát nào chứa 4 hạt trở lên. Nếu có, nó xuất ra cùng một mảng trừ việc sử dụng đệm p, và nếu không, nó thực hiện tích chập 2d để mô phỏng các hạt rơi. Động từ chính được lặp lại cho đến khi hội tụ bằng cách sử dụng toán tử công suất ^:_.

Sử dụng

   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

Mất khoảng 46 giây để tính kết quả cho n = 50000 và kết quả có thể được hiển thị bằng cách sử dụng viewmataddon với bảng màu đơn sắc.

nhân vật


2

C 229 (có rất nhiều cảnh báo)

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

Được rồi, tôi bỏ cuộc: tại sao mảng 99 của bạn là 98?
Eric Tressler

@EricTressler Làm thế nào tôi không tìm thấy điều đó trong thử nghiệm?!
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++];

đệ quy tạo cọc trong $p, ghi nhớ kích thước trong $m; sau đó in với các vòng lặp lồng nhau.
Chạy với -r.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.