Es bien sabido que una persona en una grilla bajo la influencia del alcohol tiene las mismas posibilidades de ir en cualquier dirección disponible. Sin embargo, esta declaración de sentido común no se aplica en el ámbito de los borrachos muy pequeños , cuyo comportamiento es muy similar al de tomar todos los caminos disponibles a la vez, y los posibles caminos que toman pueden interferir entre sí. Su tarea es mostrar las posibles posiciones de un borracho cuántico después de los n
pasos.
Especificación
El borracho en cuestión ocupa una cuadrícula cuadrada y puede considerarse como un autómata celular de 3 estados que utiliza un vecindario Von Neumann (en forma de más) que sigue estas simples reglas:
Empty
va aAwake
si es adyacente a exactamente unoAwake
, y de lo contrario va aEmpty
Awake
va aSleeping
Sleeping
va aSleeping
El estado inicial del tablero es un único Awake
rodeado por un campo infinito de Empty
s.
Desafío
Dado un número entero no negativo n
, cree una representación ASCII del borracho después de los n
pasos. Cada estado debe estar representado por un carácter diferente, y las soluciones deben indicar qué carácter significa qué estado. Si usa espacios para Empty
, no necesita incluir una serie de ellos al final de una línea.
Este es el código de golf , por lo que gana la respuesta más corta. Se aplican las lagunas estándar , se permiten espacios en blanco iniciales y finales, se permite la salida de matriz de cadenas / matriz de caracteres 2D, etc.
Ejemplos
Estos ejemplos usan for
Empty
, @
for Awake
y #
for Sleeping
.
n=0
@
n = 1
@
@#@
@
n = 2
@
#
@###@
#
@
n = 3
@
@#@
@ # @
@#####@
@ # @
@#@
@
n=6
@
#
@###@
@#@
@ ### @
#@# # #@#
@###########@
#@# # #@#
@ ### @
@#@
@###@
#
@
n=10
@
#
@###@
@#@
###
# # #
#######
# ### #
@ ## ### ## @
#@# ### # ### #@#
@###################@
#@# ### # ### #@#
@ ## ### ## @
# ### #
#######
# # #
###
@#@
@###@
#
@
Nota interesante
Al buscar la secuencia del número de células ocupadas en el OEIS, descubrí que el borracho cuántico es isomorfo a la secuencia de palillos de dientes mucho mejor estudiada . Si puede incorporar ese conocimiento en un mejor golf, quedaré adecuadamente impresionado.
fuente
n=10
es correcto? He intentado algunos enfoques y todos obtienen la misma respuesta (incorrecta), así que solo quiero asegurarme. Se ve un poco raro pero no lo sé.Respuestas:
Wolfram Language (Mathematica) ,
9291 bytes¡Un desafío perfecto para usar el generador incorporado de Mathematica
CellularAutomaton
!Pruébalo en línea!
Vacío = 0, Despierto = 1, Durmiendo = 2
Animación de las primeras 256 iteraciones (blanco = vacío, gris = despierto, negro = dormido):
Explicación
Ejecutar
CellularAutomaton
con especificaciones ...Aplique la regla totalista de 3 colores 7049487784884, con el vecindario de Von Neumann ...
En un tablero con un solo 1 en el medio, con un fondo de 0s ...
Repetir
<input>
veces (se{j#}
evalúa como{{{#}}}
). La matriz se expande automáticamente si una celda fuera del borde no es lo mismo que el fondoEsta regla proviene del número base-3
220221220221220221220221220
, que significa "cambiar todo1
o2
a2
, y cambiar0
a1
si y solo si hay un número impar de1
s alrededor".Imprime la matriz.
La semiprueba de "'
1
s impar ' es equivalente a 'exactamente uno1
'":Considere esta cuadrícula de píxeles de 5x5. El blanco es una
0
o una2
celda (píxeles no despiertos), y el gris es una1
celda.Si
1
se generó una celda alrededor de tres0
celdas, entonces la cuadrícula debe verse así: tiene tres1
s dispuestos en forma de U (o una versión rotada) de la siguiente manera:Debido a la autosimilitud de este autómata celular, cualquier patrón que aparezca en el autómata celular debe aparecer en diagonal (por inducción). Sin embargo, este patrón no es diagonalmente simétrico. es decir, no puede ocurrir en diagonal y no puede aparecer en ningún lugar del autómata celular.
Despertar / Dormir son equivalentes
Tenga en cuenta que una
0
celda no puede estar rodeada exactamente por una o tres2
celdas y celdas en reposo0
, ya que eso implicaría que algunos pasos anteriores, la celda tenía un vecino de una o tres1
celdas, y debe haberse convertido en un1
ya (contradicción). Por lo tanto, está bien ignorar la distinción entre1
y2
y el estado 'cambiar todo1
a1
, y0
a a1
si y solo si tiene un número impar de vecinos distintos de cero'.El autómata celular resultante es de hecho idéntico al original, la única diferencia es que no hay distinción entre borrachos "despiertos" y "dormidos". Este patrón se describe en OEIS A169707 .
Pruébalo en línea!
Comparación lado a lado de las primeras 16 iteraciones:
Agregar dos iteraciones consecutivas da un resultado que sigue las especificaciones de desafío (94 bytes):
Pruébalo en línea!
fuente
Python 2 , 192 bytes
Pruébalo en línea!
-17 bytes gracias al Sr. Xcoder
-9 bytes usando el formato de salida de Jonathan
-11 bytes gracias a Lynn
-3 bytes gracias a ovs
fuente
exec
guarda 9 bytes, y…for k in 0,1,2,3for…
guarda uno más: Enlacen=[C+k for k in-1j,1j,-1,1for C in c]
guarda un byte más!X+Y*1jin
es algo que realmente no creía que fuera posible: PC,
360354343319Las nuevas
#define
líneas después de no líneas son solo para presentación aquí, por lo que no se cuentan. Incluí una función de contenedor, por lo que es −6 (313) si la función no se cuenta y supones quen
proviene de otro lugar.q(10)
salidas:Utilizando
para vacío,
"
para dormir y!
para despierto.Esto funciona así:
A(i,b,e)
es "∀i∈ [b, e)",B(b,e)
es "∀r∈ [b, e) .∀c∈ [b, e)".Observe que después de n generaciones, el tablero es 2 n + 1 cuadrado.
Debido a la simetría del tablero, esto solo necesita simular el cuadrante inferior derecho, por lo que asignamos una matriz cuadrada n + 1 con 1 fila y columna de relleno para la búsqueda de vecino posterior (entonces n + 2).
Asignar con
calloc
nos permite multiplicar simultáneamente el ancho por la altura y despejar el tablero a0
(vacío).Al buscar una celda por sus coordenadas (
C
yD
), utiliza el valor absoluto de la fila y la columna (W
) para reflejar automáticamente las coordenadas.El tablero se almacena como un conjunto de pares de enteros que representan las generaciones actuales y anteriores. Los enteros en cuestión son
char
para que podamos evitarsizeof
.La generación que se busca con mayor frecuencia (según la prueba vecina) es la generación pasada, por lo que se coloca en el índice 0 en el par para que se pueda acceder a ella
*
.En cada generación (
g
), la generación actual se copia sobre la generación anterior utilizando unB
bucle, luego la nueva generación se genera a partir de la anterior.Cada celda se representa usando
0
para vacío,1
para despierto y2
para dormir. Contar vecinos era originalmente un cálculo del número de bits establecidos en los 4 bits bajos de la celda cuando los 4 vecinos se desplazan y OR juntos como banderas (N
),16
para dormir. Pero con la observación de que un número impar de vecinos es equivalente a exactamente 1 vecino, podemos guardar varios caracteres simplemente usando una máscara con 1.Al final, el tablero se imprime por completo iterando sobre el cuadrante inferior derecho usando el mismo truco de coordenadas de valor absoluto, menos el relleno, por lo que no imprimimos el relleno exterior en el tablero. Esta es también la razón por la cual el
B
bucle incluye un corchete de apertura, porque tenemos la instrucción de nueva línea adicional en el bucle externo.Los códigos ASCII asignan convenientemente 0 + 32 (vacío) a un espacio, 2 + 32 (durmiendo)
"
y 1 + 32 (despierto) a!
.En general, creo que este es un golf sorprendentemente legible debido a la buena estructura del problema.
fuente
putchar(10)
conputs("")
&~
no es un NAND, que quería decir que a veces pienso!(a &~ b)
en términos dea NAND (NOT b)
, aunque en este caso la lógica!
no es el mismo que el nivel de bits~
porque estamos confiando en el0
o1
resultado de!
.MATL , 39 bytes
Esto muestra
Empty
como(espacio)
Awake
como#
Sleeping
como!
.Pruébalo en línea! También puede ver crecer el patrónen el arte ASCII, o gráficamente (código modificado).
Explicación
El código utiliza números complejos
0
,1
,j
para representar los tres estados: vacío, estela, dormir, respectivamente.fuente
Befunge,
384304 bytesPruébalo en línea!
El problema al intentar implementar este tipo de cosas en Befunge es el tamaño limitado de la memoria (2000 bytes para datos y código). Así que tuve que usar un algoritmo que calcula el carácter correcto para cualquier coordenada dada sin referencia a cálculos anteriores. Lo logra al mirar recursivamente en el tiempo a través de todos los caminos posibles que el borracho podría haber seguido para llegar a ese punto.
Lamentablemente, esta no es una solución eficiente en particular. Funciona, pero es increíblemente lento, y se vuelve exponencialmente más lento cuanto mayor es el valor de n . Entonces, si bien podría funcionar para cualquier n hasta aproximadamente 127 (límite de celda de memoria de 7 bits de Befunge), en la práctica inevitablemente perderá interés esperando el resultado. En TIO, alcanzará el tiempo de espera de 60 segundos en algo más alto que alrededor de 6 (en el mejor de los casos). Un compilador funcionará mucho mejor, pero incluso entonces probablemente no quieras subir mucho más de 10.
Aún así, pensé que valía la pena enviarlo porque en realidad es una buena demostración de una "función" recursiva en Befunge.
fuente
Python 2 , 214 bytes
Pruébalo en línea!
Explicación
Usos
0
paraempty
,1
parasleeping
y2
paraawake
. Imprime una lista de caracteres bidimensionales (cadenas de una longitud).Define una función que toma un número entero no negativo
n
. Avanza sucesivamente el autómata celular hasta alcanzar el estado deseado. Finalmente, se aplica una conversión entre los valores enteros internos y los caracteres reales.fuente
Lua ,
251242239238 bytes-8 bytes al simplificar el inicializador de matriz a costa de algunos espacios en blanco iniciales adicionales.
-1 byte cambiando
c=i==2+...and print(s)
ac=i~=2+...or print(s)
.-3 bytes construyendo una cadena completa primero e imprimiendo una vez al final.
-1 byte gracias a Jonathan Frech reescribiendo
or(g(...)==1 and
comoor(1==g(...)and
.Pruébalo en línea!
Vacío =
Despertar del espacio =
1
Dormir =
0
Toma datos de la línea de comando e imprime en stdout.
Al representar los estados como
false
/nil
,1
e0
internamente, la detección de "vacío" no necesita ningún código y la verificación "exactamente uno despierto" se puede hacer con solo una adición.fuente
or(g(...)==1 and
puede seror(1==g(...)and
.APL (Dyalog) , 38 bytes
Pruébalo en línea!
-4 gracias a Adám .
-8 gracias a ngn .
fuente
Jalea ,
3929 bytesPruébalo en línea!
Usos
0
,1
y2
para vaciar despierto y dormido. El pie de página en el enlace convierte esto a,
@
y#
.ṬŒḄ
lugar deḤḶ=¹
.-
lugar de1N
. También hace¤
innecesario.S
lugar de+/
.Ḃ+Ḃ+
lugar de%3=1+=1Ḥ$+
. Ahora se usa2
para dormir en lugar de3
.Explicación que viene ...
fuente
APL (Dyalog Classic) , 38 bytes
Pruébalo en línea!
basado en la solución de Erik the Outgolfer
⍪1
es una matriz 1x1 que contiene 1⎕
entrada evaluada( )⍣⎕
aplicar eso muchas veces(⌽0,⍉)⍣4
rodear con 0s, es decir 4 veces hacer: transponer (⍉
), agregar 0s a la izquierda (0,
), invertir horizontalmente (⌽
)g←3+/0,,∘0
una función que suma triples horizontales, llámalog
⍉∘g∘⍉
una función que suma triples verticales - eso estág
bajo transposición2 | ⍉∘g∘⍉ + g←3+/0,,∘0
suma de las dos sumas módulo 2⌈
cuanto mayor entre eso y ...2∘∧
el MCM de 2 y la matriz original: esto convierte 1s en 2s, mientras conserva 0s y 2sfuente
Perl 5 , 192 + 1 (
-n
) = 193 bytesPruébalo en línea!
Utiliza 0 para vacío, 1 para despierto y 2 para dormido.
fuente
Ruby ,
164153bytesPruébalo en línea!
Utiliza "" para Vacío, "@" para Despertar y "#" para Dormir (como en el ejemplo). Supongo que podría ahorrar 6 bytes usando números, pero se ve mejor así.
fuente
Pip ,
6961 bytes60 bytes de código, +1 para
-l
bandera.Toma
n
como argumento de línea de comandos. Usos0
para vacío,1
para despertar y2
para dormir. (Para obtener un mejor arte ASCII como en los ejemplos del desafío, reemplace el finaly
con" @#"@y
).Pruébalo en línea!
Explicación
Preparar:
Bucle principal:
donde el cuerpo de la función es:
Después del ciclo, simplemente imprimimos automáticamente
y
. La-l
bandera significa que la lista anidada se imprime concatenando los contenidos de cada fila y separando las filas con nuevas líneas.fuente
Java (OpenJDK 8) , 220 bytes
Pruébalo en línea!
Nota: la matriz devuelta contiene un borde o
'\0'
caracteres. Como se supone que el plano es infinito, solo se utiliza el no borde.Mapeo de personajes:
(espacio)
=
0
Ahorra
fuente
@
verificación, ¡y encontraste la clave! Agradable. Lachar
emisión fue un descuido total de mi parte.Python,
199192 bytesEste código se ejecuta tanto en Python 2 como en Python 3, pero utiliza la popular biblioteca Numpy de terceros para hacer el manejo de la matriz.
print(f(6))
salidasSi desea una impresión más bonita, puede llamarlo de esta manera:
que imprime con los mismos caracteres que figuran en la pregunta.
fuente
[e]ach state should be represented by a different character
(interpretocharacter
como un carácter ASCII real, en lugar de un entero).