Una pila de arena abeliana , para nuestros propósitos, es una cuadrícula infinita con coordenadas enteras, inicialmente vacía de arena. Después de cada segundo, se coloca un grano de arena a (0,0). Cada vez que una celda de cuadrícula tiene 4 o más granos de arena, derrama un grano de arena a cada uno de sus cuatro vecinos simultáneamente. Los vecinos de (x, y) son (x-1, y), (x + 1, y), (x, y-1) y (x, y + 1).
Cuando una célula se derrama, puede provocar que sus vecinos se derramen. Algunos hechos:
- Esta cascada finalmente se detendrá.
- El orden en que se derraman las células es irrelevante; El resultado será el mismo.
Ejemplo
Después de 3 segundos, la cuadrícula se ve como
.....
.....
..3..
.....
.....
Después de 4 segundos:
.....
..1..
.1.1.
..1..
.....
Después de 15 segundos:
.....
..3..
.333.
..3..
.....
Y después de 16 segundos:
..1..
.212.
11.11
.212.
..1..
El reto
En el menor número de bytes posible, escriba una función que tome un solo entero positivo t y genere una imagen de la pila de arena después de t segundos.
Entrada
Un solo entero positivo t , en cualquier formato que elija.
Salida
Una imagen de la pila de arena después de t segundos, usando los caracteres
. 1 2 3
Editar: utilice los cuatro caracteres distintos que desee o dibuje una imagen. Si no está utilizando ".123" o "0123", especifique en su respuesta lo que significan los caracteres.
A diferencia de los ejemplos, su salida debe contener el número mínimo de filas y columnas necesarias para mostrar la parte distinta de cero de la pila de arena.
Es decir, para la entrada 3, la salida debe ser
3
Para 4, la salida debe ser
.1.
1.1
.1.
Puntuación
Se aplica la puntuación estándar de golf.
Reglas
No se permiten funciones de lenguaje ni bibliotecas que ya sepan qué es un sandpile.
Editar: la sección de salida se ha editado, la restricción del juego de caracteres se ha eliminado por completo. Usa cuatro caracteres o colores distintos que te gusten.
fuente
0
? ¿Cuál es la salida entonces?.
celdas vacías? ¿Podemos tener0
como una celda vacía válida?Respuestas:
R,
378343297291 bytesComo generalmente, el usuario proporciona su entrada a través de
scan()
(ya usé la variablet
, así que tomemos en suz
lugar), por lo que la segunda línea debe iniciarse por separado y luego el resto:Emite una matriz que contiene los valores de
a
ent
la generación th (0, 1, 2 o 3).Casos de prueba:
Nos ayuda que esta cosa sea simétrica tanto vertical como horizontalmente, lo que significa que el punto más a la izquierda tiene una altura de 4, esto significa que los puntos más altos, más a la derecha y más bajos también son 4.
Ah, y ¿te dije que puedes hacer hermosas visualizaciones?
Después de 1000 gotas:
Después de 50000 gotas (≈4 segundos):
Después de 333333 gotas (≈15 minutos):
¡Tú también puedes dibujarlo!
Esto tardó 4 segundos para 10000 iteraciones, pero se ralentiza considerablemente para tamaños de matriz más grandes (por ejemplo, un par de minutos para 100000 iteraciones). Es por eso que se vuelve tan lento ( calculé la tasa de crecimiento como en y obtuve τ (i) ≈689 · i ^ 1.08, por lo que el tiempo promedio por grano adicional hasta que la pila de arena se asiente después del
i
paso es ligeramente mayor que uno) , y el tiempo total en función del número de granos crece un poco más lento que cuadráticamente (T (i) ≈0.028 * i ^ 1.74):Y ahora con una explicación completa:
Esta es la primera vez en mi vida cuando el crecimiento de objetos (como
a <- c(a, 1)
) funciona mucho más rápido que preasignar una matriz grande vacía para valores y llenarla gradualmente con una tonelada de ceros sin usar.Actualizar. Golfed 18 bytes mediante la eliminación
arr.ind
enwhich
debido a Billywob y reemplazarrep(0,n)
cone=numeric;e(n)
en 5 casos debido a JDL , y 17 bytes más debido a JDL .Actualización 2. Como la pila de arena es abeliana, puede comenzar con una pila de altura deseada, por lo que eliminé el bucle redundante y obtuve un gran impulso en la productividad.
fuente
rep()
, predefiniendo , dado que lo usa 6 veces. En segundo lugar, no creo que necesite escribir laarr.ind=T
opción para lawhich()
función. Simplemente usewhich(...,T)
.n=numeric
y usar eso en su lugar, ya quen(k)
tiene menos caracteres quer(0,k)
. Aunque me gustan las fotos.1%*%0
tiene menos caracteres quearray(0,c(1,1))
. Además, el segundo argumento parau <- cbind
solo puede ser 1,cbind
lo extenderá a la longitud del primer argumento por defecto.MATL ,
5553484342 bytesInspirado por la respuesta de @ flawr .
Salida gráfica :
¡Pruébalo en MATL Online! . La entrada tarda unos 10 segundos
30
. Es posible que deba actualizar la página y presionar "Ejecutar" nuevamente si no funciona.Aquí hay un resultado de ejemplo para la entrada
100
:Salida ASCII (43 bytes) :
Pruébalo en línea!
Explicación
fuente
1Y6
.~mod(spiral(3),2)
es mucho más inteligente :-)Matlab,
160 156148 bytesPrimero se crea una matriz demasiado grande, con
n
el medio en alguna parte. Luego, la cascada se calcula con una convolución 2D muy conveniente. Al final, el exceso se recorta y todo se convierte en una cadena.Ejemplo de salida para
t=100
Como siempre:
fuente
v=any(z)
en lugar dev=find(sum(z))
(estoy usando eso en mi respuesta). Además, en2*~z
lugar de(z<1)*2
n=500
... Se había estado procesandon=400
durante varios segundos. ¿Estoy haciendo algo mal?n
este programa genera una3*n x 3*n
matriz, por lo que necesita almacenar sobre los9*n^2
números. También es totalmente ineficiente, porque también tenemos una iteración larga totalmente innecesaria desde 1 hasta n. Pero, de nuevo, esto es código golf , hacer que un programa sea eficiente es una taza de té diferente.z=sparse(zeros(2*n+1))
y cambiando el bucle for awhile any(z(:)>3)
. A continuación, puede calcular también quizás el núcleo de convolución sólo una vez:kern = 1-mod(spiral(3),2)
.Pitón 2,
195 +1 +24 =220217salida para n = 16
hay MUCHO relleno e iteraciones innecesarias, al usar
n
como límite superior "suficientemente bueno", pero n = 200 aún se completa en un segundo yn = 500 en aproximadamente 12 segundossin golf
reemplazar
return x
porimshow(x)
agrega un carácter y genera una imagen interpolada fea, agregandoimshow(x,'gray',None,1,'nearest')
elimina la interpolación borrosa que lleva la salida a las especificacionesfuente
ImportError: No module named convolve2d
. Cambiarimport scipy.signal.convolve2d as c
afrom scipy.signal import convolve2d as c
resuelve el problema. Estoy usando la versión 0.16.1 de scipy, ¿necesito una versión anterior o anterior? ¿O el problema es algo más?Perl,
157147 bytesIncluye +1 para
-p
Ejecutar con el recuento en STDIN, imprime el mapa con
0123
STDOUT:sandpile.pl
:fuente
Python
32,418385362342330 bytesEditar: guardado 6 bytes gracias a @ Qwerp-Derp
Todo el crédito a @ Andreï Kostyrka, ya que esta es una traducción directa de su código R a Python.
fuente
a,x,r
a los argumentos de la función.JavaScript,
418416406400393 bytesCrea una función anónima que muestra el resultado en la consola.
fuente
Nim, 294 caracteres
Compilar y ejecutar:
Notas:
x
se calcula como el número de columnas cero al comienzo de la fila central.x
filas y columnas de cada extremo.Actuación
fuente
Scala, 274 bytes
Uso:
scala sandpile.scala <iterations>
No creo que haya mucho que explicar sobre este. Básicamente solo agrega un grano de arena al centro. Luego verifica si es mayor que 4, si es así, se desbordará y verificará si todos los vecinos tienen más de 4, se desbordarán, etc. Es bastante rápido.
Actuación:
fuente
J, 76 bytes
Defino un verbo
p
que rellena un borde de ceros alrededor de la entrada. El verbo principal toma una matriz como entrada. Luego verifica la primera fila por cualquier pila de arena que contenga 4 o más granos. Si uno lo hace, genera la misma matriz, excepto que se usa con rellenop
, y de lo contrario realiza una convolución 2D para simular la caída de granos. El verbo principal se repite hasta la convergencia usando el operador de potencia^:_
.Uso
Se tarda unos 46 segundos en calcular el resultado para n = 50000, y el resultado se puede mostrar usando el
viewmat
complemento con un esquema de color monocromo.fuente
C 229 (con muchas advertencias)
fuente
APL (Dyalog Unicode) , SBCS de 51 bytes
Pruébalo en línea!
fuente
PHP, 213 bytes
recursivamente crea la pila adentro
$p
, recordando el tamaño adentro$m
; luego imprime con bucles anidados.Corre con
-r
.fuente