R、378の 343 297 291バイト
通常、ユーザーはscan()
(変数を既に使用しているため、代わりに使用しますt
)を介して入力を提供するz
ため、2行目を個別に起動し、残りを実行する必要があります。
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
出力の値を含む配列a
でt
世代(0、1、2または3)。
テストケース:
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
このことは、垂直方向と水平方向の両方で対称であるために役立ちます。つまり、左端のポイントの高さが4になり、最上部、右端、および最下部のポイントも4になります。
ああ、私はあなたが美しい視覚化を行うことができると言いましたか?
1000ドロップ後:
50000ドロップ後(約4秒):
333333ドロップ後(約15分):
あなたもそれを描くことができます!
image(1:n,1:n,a,col=colorRampPalette(c("#FFFFFF","#000000"))(4), axes=F, xlab="", ylab="")
この処理には10000回の反復で4秒かかりましたが、配列サイズが大きくなるとかなり遅くなります(たとえば、100000回の反復では数分)。これが非常に遅くなる理由です(成長速度をのように推定し、τ(i)≈689・i ^ 1.08を得たため、i
ステップ1 後に砂山全体が落ち着くまでの1粒あたりの平均時間は1 よりわずかに大きくなります) 、および粒子数の関数としての合計時間は、二次関数よりも少し遅くなります(T(i)≈0.028* i ^ 1.74):
そして今、完全な説明で:
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
オブジェクトの成長(などa <- c(a, 1)
)が、値に大きな空のマトリックスを事前に割り当て、未使用のゼロを徐々に埋めるよりもずっと速く動作するのは、これが私の人生で初めてです。
更新。除去することによって、18のバイトをGolfed arr.ind
においてwhich
によるBillywobと交換rep(0,n)
とe=numeric;e(n)
のために5つの例ではJDL、そしてために17バイト以上JDL。
更新2。サンドパイルはAbelianであるため、希望する高さのスタックで開始される可能性があるため、冗長ループを削除し、生産性を大幅に向上させました。
0
ますか?その時の出力は何ですか?