R,378个 343 297 291字节
通常,用户通过scan()
(我已经使用过变量t
,所以让我们z
取而代之)提供他/她的输入,因此第二行应分别启动,然后其余部分启动:
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="")
这件事花了4秒钟进行10000次迭代,但是对于较大的阵列大小(例如,几分钟进行100000次迭代),速度大大降低。这就是为什么它变得如此缓慢的原因(我估算了增长率,得到τ(i)≈689·i ^ 1.08,因此,每增加一个谷物,直到整个沙堆在i
步骤之后沉降的平均时间略大于一个)。 ,并且作为晶粒数量的函数的总时间比平方增长(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)
)的工作速度比为值预先分配一个大的空矩阵并用大量未使用的零逐渐填充它要快得多。
更新。通过去除Golfed 18个字节arr.ind
中which
由于Billywob和更换rep(0,n)
用e=numeric;e(n)
在由于5个实例JDL,和17个由于字节JDL。
更新2.由于沙堆是Abelian,它可能从所需高度的堆栈开始,因此我删除了多余的循环,从而极大地提高了生产率!
0
吗?那么输出是多少?