Huragan Matthew i Błyskawice

27

Wyzwanie

Zainspirowani tym wyzwaniem i nieprzyjemnym huraganem Matthew będziemy dynamicznie wytwarzać błyskawice.

n = 15:

   \
   /\
  /  \
 /   /
/\  /\
 /  \ \
/   / /\
   /\ \
  / /  \
 /\ \  /\
  /  \ \
 /\  /  
   \
    \
    /\

Wkład

Dodatnia liczba całkowita nokreśla głębokość rundy błyskawicy.

Zasady i ograniczenia

  • /i \należy go użyć
  • Prawdopodobieństwo kierowania pioruna jest następujące:
    • 25% Dzieli się na 2 ścieżki
    • 25% Ścieżka osiąga ślepy zaułek
    • 25% idzie w lewo
    • 25% idzie dobrze
    • Istnieje kilka wyjątków dotyczących nakładania się i ślepej uliczki poniżej:
  • Kod nie powinien być deterministyczny, nowa błyskawica powinna być generowana losowo za każdym razem
  • Śruby nie powinny zachodzić na siebie: np. Jeśli jest już śruba po lewej stronie aktualnej śruby, bieżąca śruba powinna albo się zakończyć, albo pójść w prawo, ale nie iść w lewo lub podzielić (prawdopodobieństwo nadal obowiązuje, w tym przypadku staje się 50% końcem / 50% prawo)
  • Jeśli nie istnieje inna dostępna ścieżka podziału, ścieżka nie powinna się kończyć: np. Na początku, gdy jest tylko 1 ścieżka, ścieżka nie powinna się kończyć, dopóki się nie podzieli, ma również zastosowanie, gdy istnieje wiele ścieżek, ale wszystkie oprócz jednej ścieżki są martwe , (prawdopodobieństwo zmienia się w 33% / 33% w lewo / 33% w prawo) Twoim celem jest osiągnięcie dolnej granicy
  • Białe spacje można dodać po lewej stronie (wszystko, czego potrzebujesz, to tylko wysokość-1)
  • Niezależnie od tego, czy chcesz wygenerować śrubę, zależy od Ciebie, możesz przejść od dołu do góry, od lewej do prawej itp. O ile wszystkie powyższe reguły są spełnione

Inny przykład

n = 10

 \
 /
 \
 /\
  /\
 / /
/\ \
 / /\
 \   \
 /

Huragan Matthew najwyraźniej strzela w niebo czerwonymi pociskami, zwanymi duszkami

Bądź bezpieczny i baw się dobrze grając w golfa! Proszę grać w golfa odpowiedzialnie tylko w bezpiecznym miejscu !!

Zukaberg
źródło
7
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.
Erik the Outgolfer,
17
@EriktheGolfer nie jesteś prawdziwym golfistą.
Niebieski,
4
Nie wierzę, że „Ścieżka najbardziej w centrum powinna być tą, która dociera do ziemi” jest zgodna z resztą opisu generacji losowej. Na przykład losowo możliwe jest dwukrotne podzielenie oryginalnej śruby, a następnie zakończenie dwóch środkowych śrub; jak tę możliwość można obejść, zachowując wskazane prawdopodobieństwa?
Greg Martin
Co się też stanie, jeśli (na przykład) dwa pierwsze kroki to podziały? Następnie środkowe dwie śruby stykają się ze sobą, co wydaje się problematyczne, ale także nie jest wykluczone w szczególnych przypadkach.
Greg Martin
@GregMartin Dobry punkt w środkowej części, początkowo miałem nadzieję, że wygeneruje wyważoną śrubę, ale teraz, gdy o tym myślę, nawet bez tego ograniczenia około 50% czasu powinno skończyć się gdzieś pośrodku, głębokość z 15 miałoby tylko 1-2% szansy na to, że wyląduje prawa lub lewa większość ścieżek. Usunę tę zasadę. A w przypadku części dzielącej 2 kroki jedyną rzeczą, której należy zapobiec, jest to, że żadna 2 ścieżki nie powinny się łączyć 2 ścieżkami: \/w dowolnym momencie.
Zukaberg,

Odpowiedzi:

6

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

Ton Hospel
źródło
+1 Schludnie! powinieneś dołączyć ten tester online perl -M5.010 main.pl <<< 25 , otrzymałem kilka dobrych wyników!
Zukaberg,
Czy możesz wyjaśnić trochę, jak to działa? Mam zbyt dużo zabawy z generowaniem ich haha, szczerze mówiąc, nie spodziewałem się tak dobrych rezultatów.
Zukaberg,
Niestety, musisz dodać 3 bajty-n , ponieważ liczą się także spacja i myślnik. Ta sama zasada dotyczy argumentów wiersza poleceń. Zobacz „Specjalne wywołania”, drugi punkt: Liczę je jako różnicę liczby postaci do najkrótszego równoważnego wywołania bez nich.
Erik the Outgolfer
1
@EriktheGolfer Nie, +1 jest OK, ponieważ ten program działa dobrze z wiersza poleceń, używając -nEtylko 1 znaku więcej niż -E(zobacz artykuł, do którego się odwołujesz. Pozbywa się również potrzeby -M5.010) Zawsze prezentuję mój kod jako pliki, ponieważ jest wygodniejszy, ale zawsze liczę takie opcje: Jeśli można go uruchomić z wiersza poleceń, nie liczę spacji i myślnika. Jeśli musi być w pliku (np. Ponieważ używa do$0) , liczę miejsce i myślnik
Ton Hospel
@TonHospel Oh, nie wiedziałem, że użyłeś -E. Jeśli tak, jesteś dobry.
Erik the Outgolfer,
0

JavaScript (ES6), 154 bajty

f=(n,r=[],s=" ".repeat(n)+"/",t=s.replace(/ \/|\\ |\\$/g,_=>"  /  \\/\\".substr(Math.random()*8&6,2)))=>n?/^ +$|\\\//.test(t)?f(n,r,s):f(n-1,[...r,t],t):r
<input type="number" min=1 oninput=o.textContent=f(this.value).join`\n`><pre id=o>

Zmagałem się z implementacją, dopóki nie zobaczyłem odpowiedzi @ TonHospel. W tym momencie po prostu zdegenerowała się w port. Przykładowe dane wyjściowe:

         /\
        / /\
       /\   \
        /\   \
         /\  /
          / /\
         / / /\
            / /\
            \   \
             \
Neil
źródło