Perl, 92 90 89 84 Bytes
Beinhaltet +1 für -n
Gib die Höhe auf STDIN an:
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$_
Erläuterung
Wenn Sie den Versatz des Startpunkts 0 nennen (ein Punkt befindet sich an der Ecke eines Zeichenfelds), können Sie in der nächsten Zeile nach links oder rechts gegangen sein (oder nicht) und Punkte auf Versätzen erhalten -1,1
. Die nächste Zeile gibt -2,0,2
mögliche Offsets usw. an. Sie unterscheiden sich alle um 2. Wenn Sie dann das Zeichen links unten von einem geraden Punkt und das Zeichen rechts unten ungerade nennen, können Sie dies so erweitern, dass jeder Zeichenposition gerade oder ungerade zugewiesen werden auf einer Reihe so, dass gerade und ungerade abwechseln (in der Tat ist die ganze Ebene in einem Schachbrettmuster gekachelt). Eine gerade Position kann ein /
oder haben
, eine ungerade Position kann ein \
oder haben
.
Das Zeichen kurz vor a /
befindet sich an einer ungeraden Position, also könnte es entweder \
oder sein
, ist aber \/
verboten, also nur
möglich. Ebenso ist der Charakter nach einem \
muss eine sein
(vorausgesetzt , die Reihe mit genug Platz links gepolstert und rechts so die Zeilengrenzen kein Problem sind). Ein Blitz setzt sich also in der nächsten Reihe immer direkt unter einem \
oder unter einem fort /
. In jedem Fall ist der untere Punkt in der Mitte , und die nächste Zeile kann eine von haben
, /
, \
oder /\
direkt unter den oberen 2 Zeichen. Um die nächste Zeile zu generieren, kann ich einfach ein beliebiges \
oder ersetzen/
durch eine dieser 4 Erweiterungen mit gleicher Wahrscheinlichkeit (Sie können das erste Zeichen auch unabhängig durch
oder /
und das zweite Zeichen durch
oder ersetzen \
). In Perl könnte man das mit etwas machen wie:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Wenn die resultierende Zeile jedoch enthält \/
(verboten beitreten) oder nicht /
oder \
auf allen (Riegel stirbt und erreicht nicht den Boden) ist das Ergebnis ungültig. In diesem Fall werfe ich die ganze Reihe weg und versuche es einfach noch einmal. Es gibt immer eine gültige Fortsetzung, und wenn Sie oft genug versuchen, wird eine gefunden (z. B. stirbt bis auf einen Durchlauf alles). Dies ist eine etwas andere Wahrscheinlichkeitsverteilung als der vorgeschlagene Anti-Überlappungs-Algorithmus, aber ich denke, dies ist in der Tat besser, da er keine Richtungsverzerrung aufweist. Die Gültigkeit kann auf golferische Weise mit getestet werden
m#\\|/#>m#\\/#
Das Problem dabei ist, dass die zufällige Substitution so looooang ist und all diese Escape-Zeichen \
auch Bytes essen. Also habe ich beschlossen , meine Zeilen mit Ziffernfolgen zu bauen und ersetzen die entsprechenden Ziffern durch
, /
und \
gerade vor dem Druck. Die grundlegende zufällige Ersetzung ist
53|16*rand
das gibt einer von 53
, 55
, 61
oder 63
mit gleicher Wahrscheinlichkeit. Ich interpretiere dann 5
und 1
als
, 3
als \
und 6
als /
. Das erklärt den Zeilendruck:
say y|3615|\\/ |r
In einem ernsthaften Golfwettbewerb würde ich jetzt systematisch alternative magische Formeln untersuchen, aber dies sollte ziemlich gut sein (innerhalb von 3 Bytes des Optimums).
Die restlichen Komponenten des Programms:
1x$_.6
Dies initialisiert $_
(siehe nächste Karte) Höhenräume, gefolgt von a /
. Dies ist eine unsichtbare Zeile über der ersten, die gedruckt wird, und stellt sicher, dass das Feld breit genug ist, damit der Bolzen links nicht leer wird
map{ ... ; say ...}(1x$_.6)x$_
Ich werde dieselbe anfängliche Zeichenkettenhöhe verarbeiten, um jedes Mal eine neue Zeile zu drucken
$_=$;until$;=$_,...
Speichern Sie die aktuelle Zeile in $;
. Wenn sich herausstellt, dass die Ersetzung ungültig ist, stellen Sie sie $_
von wieder her$;
s/.6|3.?/53|16*rand/eg
Führen Sie die eigentliche Substitution durch. Ich muss nicht überprüfen , was vor ist /
oder nach , \
da es muss ein Raum sein. Dies ist praktisch, da der Raum entweder durch 1
oder dargestellt werden kann 5
. Da ich die Zeichenfolge nur nach links aufgefüllt habe, \
darf das Leerzeichen nach dem noch fehlen, machen Sie dieses Zeichen also optional
/3|6/>/36/
Überprüfen Sie, ob die neue Zeile gültig ist
Stay safe and have fun golfing!
Möglicherweise geben Sie auch an, dass Sie bei einem Streik von EAS alles aufgeben und die Anweisungen befolgen müssen! Golf Code ist nicht Ihre Priorität in einer solchen Situation.