Perl, 92 90 89 84 bytes
Incluye +1 para -n
Dar altura en STDIN:
perl -M5.010 bolt.pl <<< 15
bolt.pl
:
#!/usr/bin/perl -n
map{$_=$;until$;=$_,s/.6|3.?/53|16*rand/eg,/3|6/>/36/;say y|3615|\\/ |r}(1x$_.6)x$_
Explicación
Si llama al desplazamiento del punto de inicio 0 (un punto está en la esquina de un cuadro de caracteres), en la siguiente fila puede haber ido hacia la izquierda o hacia la derecha (o no) y puede terminar con puntos en los desplazamientos -1,1
. La siguiente fila muestra los -2,0,2
posibles desplazamientos, etc. Todos difieren en 2. Si luego llama al carácter a la esquina inferior izquierda de un punto par y el carácter a la esquina inferior derecha impar, puede extenderlo para asignar pares o impares a cada posición de carácter. en una fila tal que la alternativa par e impar (de hecho, todo el plano está en mosaico en un patrón de tablero de ajedrez). Una posición par puede tener un /
o
, una posición impar puede tener \
o
.
El personaje justo antes de a /
está en una posición extraña, por lo que podría ser uno \
o
, pero \/
está prohibido, por lo que solo
es posible. Del mismo modo, el carácter después de a \
debe ser a
(suponiendo que la fila esté rellenada con suficientes espacios a la izquierda y a la derecha para que los límites de la fila no sean un problema). Entonces un rayo continúa en la siguiente fila siempre directamente debajo de \
ao debajo de a /
. En cualquier caso, el punto más bajo está en el medio y la siguiente fila puede tener uno de
, /
, \
o /\
directamente debajo de la tapa 2 caracteres. Entonces, para generar la siguiente fila, simplemente puedo reemplazar cualquiera \
o/
por cualquiera de estas 4 expansiones con igual probabilidad (también podría reemplazar independientemente el primer carácter por
o /
y el segundo carácter por
o \
). En perl podrías hacer esto con algo como:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Si la fila resultante sin embargo contiene \/
(prohibido unirse a) o ninguna /
, o \
en todos los troqueles (pernos y no llega a la parte inferior) el resultado no es válido. En ese caso, tiro toda la fila y simplemente intento de nuevo. Siempre existe una continuación válida y si intenta con suficiente frecuencia se encontrará una (por ejemplo, todo muere excepto por 1 flujo). Esta es una distribución de probabilidad ligeramente diferente del algoritmo anti-superposición sugerido, pero creo que de hecho es mejor ya que no tiene sesgo direccional. La validez se puede probar de forma golfística utilizando
m#\\|/#>m#\\/#
El problema aquí es que la sustitución aleatoria es muy larga y todos estos \
escapes también comen bytes. Así que decidí construir mis filas usando cadenas de dígitos y reemplazar los dígitos apropiados por
, /
y \
justo antes de imprimir. El reemplazo aleatorio básico es
53|16*rand
lo que da una de 53
, 55
, 61
o 63
con igual probabilidad. Luego interpreto 5
y 1
as
, 3
as \
y 6
as /
. Eso explica la impresión de la fila:
say y|3615|\\/ |r
En una competencia de golf seria, ahora comenzaría a explorar sistemáticamente fórmulas mágicas alternativas, pero esto debería ser bastante bueno (dentro de 3 bytes de óptimo)
El resto de los componentes del programa:
1x$_.6
Esto inicializa $_
(ver el siguiente mapa) a espacios de altura seguidos de a /
. Esta es una fila invisible encima de la primera que se imprime y se asegura de que el campo sea lo suficientemente ancho para que el perno nunca se quede sin espacio a la izquierda
map{ ... ; say ...}(1x$_.6)x$_
Procesaré esta misma altura de cadena inicial veces imprimiendo una nueva fila cada vez
$_=$;until$;=$_,...
Guardar la fila actual en $;
. Si el reemplazo resulta no válido, restaure $_
desde$;
s/.6|3.?/53|16*rand/eg
Haz la sustitución real. No tengo que verificar qué es antes /
o después, \
ya que debe ser un espacio. Esto es conveniente ya que el espacio puede ser representado por 1
o 5
. Como solo acolché la cadena a la izquierda, el espacio después de \
que todavía puede estar ausente, así que haga que ese carácter sea opcional
/3|6/>/36/
Verifique si la nueva fila es válida
Stay safe and have fun golfing!
¡Quizás también especifique que si EAS ataca, abandone todo y siga las órdenes! El código de golf no es su prioridad en tal situación.