Uma pilha de areia abeliana , para nossos propósitos, é uma grade infinita com coordenadas inteiras, inicialmente vazias de areia. Após cada segundo, um grão de areia é colocado em (0,0). Sempre que uma célula da grade possui 4 ou mais grãos de areia, ela derrama um grão de areia para cada um de seus quatro vizinhos simultaneamente. Os vizinhos de (x, y) são (x-1, y), (x + 1, y), (x, y-1) e (x, y + 1).
Quando uma célula é derramada, pode causar derramamento de seus vizinhos. Alguns fatos:
- Essa cascata acabará eventualmente.
- A ordem na qual as células se derramam é irrelevante; O resultado será o mesmo.
Exemplo
Após 3 segundos, a grade parece
.....
.....
..3..
.....
.....
Após 4 segundos:
.....
..1..
.1.1.
..1..
.....
Após 15 segundos:
.....
..3..
.333.
..3..
.....
E depois de 16 segundos:
..1..
.212.
11.11
.212.
..1..
O desafio
No menor número de bytes possível, escreva uma função que use um único número inteiro positivo t e mostre uma imagem do monte de areia após t segundos.
Entrada
Um único número inteiro positivo t , em qualquer formato que você escolher.
Resultado
Uma imagem do monte de areia após t segundos, usando os caracteres
. 1 2 3
Editar: use quaisquer quatro caracteres distintos que desejar ou faça um desenho. Se você não estiver usando ".123" ou "0123", especifique na sua resposta o que os caracteres significam.
Diferentemente dos exemplos, sua saída deve conter o número mínimo de linhas e colunas necessárias para mostrar a parte diferente de zero do sandpile.
Ou seja, para a entrada 3, a saída deve ser
3
Para 4, a saída deve ser
.1.
1.1
.1.
Pontuação
A pontuação de golfe padrão se aplica.
Regras
Não são permitidas funções de linguagem ou bibliotecas que já sabem o que é um monte de areia.
Editar: a seção de saída foi editada, a restrição do conjunto de caracteres foi completamente removida. Use quatro caracteres ou cores distintas que desejar.
fonte
0
? Qual é o resultado, então?.
células vazias? Podemos ter0
como uma célula vazia válida?Respostas:
R,
378343297291 bytesComo normalmente, o usuário fornece sua entrada via
scan()
(eu já usei a variávelt
, então vamos usarz
), para que a segunda linha seja lançada separadamente e depois o resto:Gera uma matriz que contém os valores de
a
nat
geração (0, 1, 2 ou 3).Casos de teste:
Isso nos ajuda a que isso seja simétrico tanto vertical quanto horizontalmente, o que significa que o ponto mais à esquerda recebe uma altura de 4, o que significa que os pontos mais alto, mais à direita e mais baixos também são 4.
Ah, e eu disse que você pode fazer belas visualizações?
Após 1000 gotas:
Após 50000 quedas (≈4 segundos):
Após 333333 quedas (± 15 minutos):
Você pode desenhá-lo também!
Isso levou 4 segundos para 10000 iterações, mas diminuiu consideravelmente para tamanhos de matriz maiores (por exemplo, alguns minutos para 100000 iterações). É por isso que fica tão lento (eu estimei a taxa de crescimento como em e obtive τ (i) ≈689 · i ^ 1,08; portanto, o tempo médio por um grão adicional até que toda a pilha de areia assente após
i
a etapa seja um pouco maior que um) , e o tempo total em função do número de grãos cresce um pouco mais lentamente do que quadraticamente (T (i) ≈0,028 * i ^ 1,74):E agora com uma explicação completa:
Esta é a primeira vez na minha vida em que objetos em crescimento (como
a <- c(a, 1)
) funcionam muito mais rápido do que pré-alocar uma grande matriz vazia de valores e preenchê-la gradualmente com uma tonelada de zeros não utilizados.Atualizar. Golfed 18 bytes, removendo
arr.ind
emwhich
virtude Billywob e substituindorep(0,n)
come=numeric;e(n)
em 5 casos, devido à JDL , e mais de 17 bytes, devido à JPL .Atualização 2. Como a pilha de areia é abeliana, ela pode começar com uma pilha da altura desejada, então removi o loop redundante e ganhei um enorme aumento de produtividade!
fonte
rep()
, predefinindo , desde que você o use 6 vezes. Em segundo lugar, não acho que você precise escrever aarr.ind=T
opção para awhich()
função. Basta usarwhich(...,T)
.n=numeric
e usar isso, poisn(k)
há menos caracteres quer(0,k)
. Eu gosto das fotos embora.1%*%0
há menos caracteres quearray(0,c(1,1))
. Além disso, o segundo argumentou <- cbind
pode ser apenas 1,cbind
estendendo-o para o tamanho do primeiro argumento por padrão.MATL ,
5553484342 bytesInspirado pela resposta de @ flawr .
Saída gráfica :
Experimente no MATL Online! . Demora cerca de 10 segundos para entrada
30
. Pode ser necessário atualizar a página e pressionar "Executar" novamente se não funcionar.Aqui está um exemplo de resultado para entrada
100
:Saída ASCII (43 bytes) :
Experimente online!
Explicação
fonte
1Y6
.~mod(spiral(3),2)
é :-) muito mais inteligenteMatlab,
160 156148 bytesPrimeiro, é criada uma matriz muito grande, com a
n
no meio em algum lugar. Então a cascata é calculada com uma convolução 2D muito conveniente. No final, o excesso é cortado e a coisa toda é convertida em uma string.Exemplo de saída para
t=100
Como sempre:
fonte
v=any(z)
em vez dev=find(sum(z))
(estou usando isso na minha resposta). Além disso, em2*~z
vez de(z<1)*2
n=500
... Ele estava sendo processadon=400
por vários segundos. Estou fazendo algo errado?n
deste programa gere uma3*n x 3*n
matriz, é necessário armazenar sobre9*n^2
números. Também é totalmente ineficiente, porque também temos uma iteração longa totalmente desnecessária de 1 a n. Mas, novamente, isso é código-golfe , tornar um programa eficiente é uma xícara de chá diferente.z=sparse(zeros(2*n+1))
e alterando o loop for parawhile any(z(:)>3)
. Depois, você pode talvez também calcular o kernel de convolução apenas uma vez:kern = 1-mod(spiral(3),2)
.Python 2,
195 +1 +24 = 220217saída para n = 16
há MUITO preenchimento e iterações desnecessários, usando
n
como um limite superior "suficientemente bom", mas n = 200 ainda é concluído em um segundo en = 500 em cerca de 12 segundosdestroçado
substituir
return x
porimshow(x)
adiciona um caractere e gera uma imagem interpolada feia; a adiçãoimshow(x,'gray',None,1,'nearest')
remove a interpolação tremida, elevando a saída às especificaçõesfonte
ImportError: No module named convolve2d
. Alterarimport scipy.signal.convolve2d as c
parafrom scipy.signal import convolve2d as c
resolver o problema. Estou usando o scipy versão 0.16.1, preciso de uma versão mais antiga ou mais recente? Ou a questão é outra coisa?Perl,
157147 bytesInclui +1 para
-p
Execute com a contagem em STDIN, imprima o mapa usando
0123
para STDOUT:sandpile.pl
:fonte
Python
32,418385362342330 bytesEdit: salvou 6 bytes graças a @ Qwerp-Derp
Todo o crédito para @ Andreï Kostyrka, pois esta é uma tradução direta de seu código R para Python.
fonte
a,x,r
para os argumentos da função.JavaScript,
418416406400393 bytesCria uma função anônima que exibe a saída no console.
fonte
Nim, 294 caracteres
Compilar e executar:
Notas:
x
é calculado como o número de zero colunas no início da linha do meio.x
linhas e colunas de cada extremidade.atuação
fonte
Scala, 274 bytes
Uso:
scala sandpile.scala <iterations>
Eu não acho que haja muito o que explicar sobre este. Basicamente, apenas adiciona um grão de areia ao centro. Em seguida, verifica se é maior que 4, se for o caso, transborda e verifica se todos os vizinhos são maiores que 4, transbordam, etc. É bastante rápido.
Atuação:
fonte
J, 76 bytes
Eu defino um verbo
p
que preenche uma borda de zeros ao redor da entrada. O verbo principal recebe uma matriz como entrada. Em seguida, verifica a primeira linha em busca de qualquer pilha de areia que contenha 4 ou mais grãos. Se o fizer, ele gera a mesma matriz, exceto o uso acolchoadop
e, caso contrário, realiza a convolução 2d para simular a queda de grãos. O verbo principal é repetido até a convergência usando o operador de energia^:_
.Uso
Demora cerca de 46 segundos para calcular o resultado para n = 50000, e o resultado pode ser exibido usando o
viewmat
complemento com um esquema de cores monocromático.fonte
C 229 (com muitos avisos)
fonte
APL (Dyalog Unicode) , 51 bytes SBCS
Experimente online!
fonte
PHP, 213 bytes
recursivamente cria a pilha
$p
, lembrando o tamanho$m
; depois imprime com loops aninhados.Corra com
-r
.fonte