Perl, 92 90 89 84 bajtów
Obejmuje +1 dla -n
Podaj wysokość 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$_
Wyjaśnienie
Jeśli wywołasz przesunięcie punktu początkowego 0 (punkt znajduje się na rogu pola znaków), to w następnym rzędzie możesz przejść w lewo lub w prawo (lub nie) i może skończyć się punktami na przesunięciach -1,1
. Następny wiersz podaje -2,0,2
możliwe przesunięcia itp. Wszystkie różnią się o 2. Jeśli następnie wywołasz znak w dolnej lewej części punktu parzystej, a znak w dolnej prawej parze nieparzystej, możesz rozszerzyć tę funkcję o przypisanie parzystej lub nieparzystej pozycji każdej postaci w rzędzie takim, że parzysta i nieparzysta naprzemiennie (w rzeczywistości cała płaszczyzna jest wyłożona kafelkami). Pozycja parzysta może mieć /
lub
, a pozycja nieparzysta może mieć \
lub
.
Postać tuż przed /
jest w dziwnym położeniu więc to może być \
albo
, ale \/
zabronione jest więc tylko
jest to możliwe. Podobnie znak po a \
musi być a
(zakładając, że wiersz jest wypełniony wystarczającą ilością miejsca po lewej i prawej stronie, więc granice wierszy nie stanowią problemu). Tak więc błyskawica kontynuuje w następnym rzędzie zawsze bezpośrednio pod a \
lub poniżej a /
. W każdym przypadku, temperatura w dolnej połowie i następny rząd może mieć jeden
, /
, \
lub /\
bezpośrednio poniżej 2 górnych znaków. Aby wygenerować następny wiersz, mogę po prostu zastąpić dowolny \
lub/
przez dowolne z tych 4 rozszerzeń z jednakowym prawdopodobieństwem (możesz również niezależnie zastąpić pierwszy znak przez
lub, /
a drugi znak przez
lub \
). W Perlu możesz to zrobić za pomocą czegoś takiego:
s#\\ | /#(" "," \\","/ ","/\\")[rand 4]#eg
Jeśli wynikowy rząd zawiera jednak \/
(zabronione łączenie) lub nie ma go wcale /
lub \
wcale (śruba umiera i nie dochodzi do dołu) wynik jest nieprawidłowy. W takim przypadku wyrzucam cały rząd i po prostu próbuję ponownie. Prawidłowa kontynuacja zawsze istnieje, a jeśli spróbujesz wystarczająco często, znajdziesz ją (np. Wszystko umiera oprócz 1 przepływu). Jest to nieco inny rozkład prawdopodobieństwa niż sugerowany algorytm zapobiegający nakładaniu się, ale myślę, że w rzeczywistości jest to lepsze, ponieważ nie ma ukierunkowania kierunkowego. Ważność może być testowana w golfowy sposób przy użyciu
m#\\|/#>m#\\/#
Problem polega na tym, że losowe podstawienie jest tak długie, a wszystkie te \
ucieczki również jedzą bajty. Więc postanowiłem zbudować moje wiersze używając ciągi cyfr i wymienić odpowiednie cyfry
, /
a \
tuż przed drukowaniem. Podstawowym losowym zamiennikiem jest
53|16*rand
co daje jeden 53
, 55
, 61
lub 63
z jednakowym prawdopodobieństwem. Następnie interpretuję 5
i 1
jako
, 3
jako \
i 6
jako /
. To wyjaśnia wydruk wiersza:
say y|3615|\\/ |r
W poważnych zawodach golfowych zacznę teraz systematycznie badać alternatywne formuły magiczne, ale powinno to być całkiem dobre (w granicach 3 bajtów od optymalnego)
Reszta składników programu:
1x$_.6
Inicjuje się $_
(patrz następna mapa) do wysokości pomieszczeń, po których następuje /
. Jest to niewidoczny rząd nad pierwszym drukowanym wierszem i upewnia się, że pole jest wystarczająco szerokie, aby śruba nigdy nie zabrakło miejsca po lewej stronie
map{ ... ; say ...}(1x$_.6)x$_
Przetwarzam ten sam początkowy ciąg znaków razy drukując nowy wiersz za każdym razem
$_=$;until$;=$_,...
Zapisz bieżący wiersz w $;
. Jeśli wymiana okaże się nieprawidłowa, przywróć $_
z$;
s/.6|3.?/53|16*rand/eg
Dokonaj rzeczywistej zamiany. Nie muszę sprawdzać, co jest przed /
ani po, \
ponieważ musi to być spacja. Jest to wygodne, ponieważ przestrzeń może być reprezentowana przez jeden 1
lub 5
. Ponieważ dopełniłem ciąg tylko w lewo, spacja po tym, jak \
nadal może być nieobecna, więc ustaw tę postać opcjonalnie
/3|6/>/36/
Sprawdź, czy nowy wiersz jest prawidłowy
Stay safe and have fun golfing!
Może także sprecyzować, że jeśli EAS uderzy, porzuć wszystko i wykonuj rozkazy! W takiej sytuacji kod golfowy nie jest Twoim priorytetem.