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,2moż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, 61lub 63z jednakowym prawdopodobieństwem. Następnie interpretuję 5i 1jako , 3jako \i 6jako /. 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 1lub 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.