Perl, 92 90 89 84 bytes
Inclui +1 para -n
Dê altura em 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$_
Explicação
Se você chamar o deslocamento do ponto inicial 0 (um ponto está no canto de uma caixa de caractere), na próxima linha você poderá ter ido para a esquerda ou direita (ou não) e poderá acabar com pontos em compensações -1,1
. A próxima linha fornece os -2,0,2
possíveis desvios, etc. Eles diferem por 2. Se você chamar o caractere para o canto inferior esquerdo de um ponto par e o caractere para o canto inferior direito, você poderá estender isso para atribuir pares ou ímpares a cada posição do personagem em uma fileira que alterna par e ímpar (na verdade, todo o plano é lado a lado em um padrão quadriculado). Uma posição par pode ter um /
ou
, uma posição ímpar pode ter \
ou
.
O personagem imediatamente antes de a /
está em uma posição ímpar, de modo que pode ser um \
ou outro
, mas \/
é proibido apenas para que
seja possível. Da mesma forma, o caractere após a \
deve ser a
(assumindo que a linha seja preenchida com espaços suficientes à esquerda e à direita, para que os limites da linha não sejam problema). Assim, um raio continua na próxima linha sempre diretamente abaixo de a \
ou abaixo de a /
. Em qualquer caso, o ponto mais baixo está no meio e a fileira seguinte pode ter um de
, /
, \
ou /\
directamente abaixo da parte superior 2 caracteres. Então, para gerar a próxima linha, posso simplesmente substituir qualquer \
ou/
por qualquer uma dessas 4 expansões com igual probabilidade (você também pode substituir independentemente o primeiro caractere por
ou /
e o segundo caractere por
ou \
). Em perl, você pode fazer isso com algo como:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Se a linha resultante no entanto contém \/
(proibido juntar-se) ou não /
ou \
em todos (dies parafuso e não chegar ao fundo), o resultado é inválido. Nesse caso, jogo fora toda a linha e simplesmente tento novamente. Sempre existe uma continuação válida e, se você tentar com frequência, será encontrada uma (por exemplo, tudo morre, exceto 1 fluxo). Essa é uma distribuição de probabilidade um pouco diferente do algoritmo anti-sobreposição sugerido, mas acho que isso é realmente melhor, pois não possui viés direcional. A validade pode ser testada de maneira golfista usando
m#\\|/#>m#\\/#
O problema aqui é que a substituição aleatória é muito lenta e todas essas \
fugas também comem bytes. Por isso, decidi construir minhas linhas usando cadeias de dígitos e substituir os dígitos apropriados por
, /
e \
pouco antes da impressão. A substituição aleatória básica é
53|16*rand
o que dá uma das 53
, 55
, 61
ou 63
com igual probabilidade. Eu então interpreto 5
e 1
como
, 3
como \
e 6
como /
. Isso explica a impressão da linha:
say y|3615|\\/ |r
Em uma competição de golfe séria, eu começaria a explorar sistematicamente fórmulas mágicas alternativas, mas isso deve ser muito bom (a menos de 3 bytes do ideal)
O restante dos componentes do programa:
1x$_.6
Isso inicializa $_
(veja o próximo mapa) para espaços de altura seguidos por a /
. Esta é uma linha invisível acima da primeira que está sendo impressa e garante que o campo seja amplo o suficiente para que o parafuso nunca fique sem espaço à esquerda
map{ ... ; say ...}(1x$_.6)x$_
Eu processarei essa mesma altura inicial da string vezes imprimindo uma nova linha a cada vez
$_=$;until$;=$_,...
Salve a linha atual em $;
. Se a substituição for uma restauração inválida $_
de$;
s/.6|3.?/53|16*rand/eg
Faça a substituição real. Não preciso verificar o que é antes /
ou depois, \
pois deve ser um espaço. Isso é conveniente, pois o espaço pode ser representado por um 1
ou por um 5
. Como eu apenas coloquei a corda à esquerda, o espaço após a \
continuação ainda pode estar ausente, portanto, torne esse caractere opcional
/3|6/>/36/
Verifique se a nova linha é válida
Stay safe and have fun golfing!
Talvez também especifique que, se o EAS ocorrer, abandone tudo e siga as ordens! Código de golfe não é sua prioridade em tal situação.