Perl, 92 90 89 84 byte
Include +1 per -n
Dare altezza su 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$_
Spiegazione
Se chiami l'offset del punto iniziale 0 (un punto si trova nell'angolo di una casella di carattere), nella riga successiva puoi essere andato a sinistra o a destra (o no) e puoi finire con punti sugli offset -1,1
. La riga successiva indica -2,0,2
come possibili offset ecc. Differiscono tutti per 2. Se poi chiami il personaggio in basso a sinistra di un punto pari e il carattere in basso a destra dispari puoi estenderlo all'assegnazione di pari o dispari a ogni posizione del personaggio su una fila tale che si alternino pari e dispari (in effetti l'intero piano è piastrellato a scacchiera). Una posizione pari può avere /
o
, una posizione dispari può avere \
o
.
Il personaggio appena prima di a /
è in una posizione strana, quindi potrebbe essere uno \
o
, ma \/
è proibito, quindi
è possibile solo . Allo stesso modo, il carattere dopo a \
deve essere a
(supponendo che la riga sia riempita con spazi sufficienti a sinistra e a destra, quindi i confini della riga non sono un problema). Quindi un fulmine continua nella riga successiva sempre direttamente sotto a \
o sotto a /
. In entrambi i casi il punto più basso è nel mezzo e la riga successiva può avere uno dei
, /
, \
o /\
direttamente sotto i primi 2 caratteri. Quindi per generare la riga successiva posso semplicemente sostituire qualsiasi \
o/
con una di queste 4 espansioni con uguale probabilità (puoi anche sostituire in modo indipendente il primo carattere con
oe /
il secondo carattere con
o \
). In perl potresti farlo con qualcosa del tipo:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Se la riga risultante contiene comunque \/
(unione proibita) o no /
o \
affatto (il bullone muore e non raggiunge il fondo) il risultato non è valido. In tal caso, butto via l'intera riga e semplicemente riprovo. Esiste sempre una continuazione valida e se ci provi abbastanza spesso ne verrà trovata una (ad es. Tutto muore tranne 1 flusso). Questa è una distribuzione di probabilità leggermente diversa dall'algoritmo suggerito anti-sovrapposizione, ma penso che sia effettivamente migliore poiché non ha distorsioni direzionali. La validità può essere testata in modo golfistico utilizzando
m#\\|/#>m#\\/#
Il problema qui è che la sostituzione casuale è così lunga e tutte queste \
fughe mangiano anche byte. Così ho deciso di costruire le mie righe usando stringhe di cifre e sostituire le cifre appropriate con
, /
e \
appena prima di stampare. La sostituzione casuale di base è
53|16*rand
che dà una delle 53
, 55
, 61
o 63
con la stessa probabilità. Poi interpreto 5
e 1
come
, 3
come \
e 6
come /
. Questo spiega la stampa di righe:
say y|3615|\\/ |r
In una seria competizione di golf ora inizierei a esplorare sistematicamente formule magiche alternative, ma questo dovrebbe essere abbastanza buono (entro 3 byte dall'ottimale)
Il resto dei componenti del programma:
1x$_.6
Questo inizializza $_
(vedi la mappa successiva) agli spazi di altezza seguiti da a /
. Questa è una riga invisibile sopra la prima che viene stampata e si assicura che il campo sia abbastanza largo in modo che il bullone non possa mai esaurire lo spazio a sinistra
map{ ... ; say ...}(1x$_.6)x$_
Elaborerò la stessa altezza iniziale della stringa volte a stampare una nuova riga ogni volta
$_=$;until$;=$_,...
Salva la riga corrente in $;
. Se la sostituzione risulta non valida ripristinare $_
da$;
s/.6|3.?/53|16*rand/eg
Effettua la sostituzione effettiva. Non devo controllare ciò che è prima /
o dopo \
poiché deve essere uno spazio. Questo è conveniente poiché lo spazio può essere rappresentato da uno 1
o 5
. Dal momento che ho solo riempito la stringa a sinistra dello spazio dopo che \
può ancora essere assente, quindi rendere quel carattere opzionale
/3|6/>/36/
Controlla se la nuova riga è valida
Stay safe and have fun golfing!
Forse anche specificare che se l'EAS colpisce, abbandonare tutto e seguire gli ordini! Il codice del golf non è la tua priorità in una situazione del genere.