Befunge, 344 bajty
&v>>>#p_:63p:43g`\!+v>/*53g+\01g:2%2*1-\2/!*63g+\0\:v
40$ v++!\`g14:p35:\<^2\-1*2%2p10::%4+g00:\g36\g35-1_v
#11^$_83p73v >1+:41g`!#v_$,1+:43g`!#v_@>->2>+00p+141^_
<p1^ vp< ^,g+7g36:<<<<1+55p36:<<<< ^1?0^#7g36g35*
8&p|!++!%9#2g+7g10\*!-g38g10!-g37:g00!!*<>3^
443>:!#v_>>1-::3%1-:53g+00p\3/1-:63g+01p^
^>^>>$#<"#"53g63g7+p41g53g-43g63g-+!#^_
Wypróbuj online!
Jak wspomniano @flawr w odpowiedzi MATLAB, może to trochę potrwać, jeśli rozmiar pola ma dowolny nietrywialny rozmiar. W rzeczywistości dość łatwo jest wpaść w sytuację, w której naprawdę nie warto czekać na jej zakończenie, ponieważ prawdopodobnie czekasz do końca czasu.
Aby zrozumieć, dlaczego tak się dzieje, pomocne jest wyświetlenie programu uruchamianego w jednym z wielu „wizualnych debuggerów” Befunge. Ponieważ dane i kod są takie same w Befunge, będziesz mógł zobaczyć ścieżkę, która zmienia się w czasie. Na przykład, tutaj jest krótka animacja pokazująca, jak może wyglądać część biegu na wolnej ścieżce.
Gdy algorytm zdecyduje się wykonać ten fatalny zwrot w lewo u dołu granicy pola, zasadniczo skazał się na całe życie bezcelowej wędrówki. Od tego momentu musi podążać każdą możliwą ścieżką na tym odgrodzonym terenie, zanim będzie mógł się wycofać i spróbować skręcić w prawo. A liczba potencjalnych ścieżek w tych przypadkach może łatwo stać się astronomiczna.
Konkluzja: Jeśli wydaje się, że zajmuje to dużo czasu, prawdopodobnie dobrym pomysłem jest po prostu przerwać wykonywanie i zacząć od nowa.
Wyjaśnienie
Jest to w zasadzie algorytm rekurencyjny, wypróbowujący każdą możliwą ścieżkę przez pole, a następnie odwijający kroki, które zostały już wykonane, gdy tylko utknie. Ponieważ Befunge nie ma pojęcia funkcji, funkcja rekurencyjna nie wchodzi w rachubę, ale możemy naśladować ten proces, śledząc stan na stosie.
Działa to poprzez wypełnienie stosu potencjalnymi współrzędnymi, które możemy chcieć śledzić. Następnie wyciągamy jeden zestaw ze stosu i sprawdzamy, czy jest on odpowiedni (tj. W zasięgu i nie pokrywa się z istniejącą ścieżką). Kiedy już znajdziemy dobre miejsce, zapisujemy #
na polu gry w tej lokalizacji i dodajemy te szczegóły do stosu, na wypadek, gdybyśmy musieli później wrócić.
Następnie wypychamy dodatkowe cztery zestawy współrzędnych na stos (w losowej kolejności), wskazując potencjalne ścieżki, które możemy wziąć z tej nowej lokalizacji, i przeskakujemy z powrotem na początek pętli. Jeśli żadna z potencjalnych ścieżek nie jest wykonalna, przejdziemy do punktu na stosie, w którym zapisaliśmy lokalizację, #
którą wypisaliśmy, więc cofniemy ten krok i będziemy kontynuować próbę potencjalnych współrzędnych z poprzedniego kroku.
Oto jak wygląda kod z wyróżnionymi różnymi częściami komponentu:
Odczytaj szerokość i wysokość pola i popchnij współrzędne początkowe wraz ze 0
znacznikiem typu, aby wskazać potencjalną ścieżkę, a nie lokalizację cofania.
Sprawdź lokalizacje cofania (wskazane przez 1
znacznik typu), które są cofane za pomocą prostej p
komendy, ponieważ są przechowywane w dokładnie takim formacie, jaki jest potrzebny do zapisania miejsca z powrotem na polu gry.
Sprawdź, czy współrzędne nadal znajdują się na polu gry. Jeśli są poza zasięgiem, upuść je ze stosu i zapętl z powrotem, aby wypróbować następne potencjalne współrzędne.
Jeśli są w zasięgu, pobierz dwie kolejne wartości ze stosu, czyli lokalizacji z poprzedniego kroku (wymagane w teście, który następuje po tym).
Sprawdź, czy współrzędne mają zetknąć się z istniejącym segmentem ścieżki. Lokalizacja poprzedniego kroku jest oczywiście ignorowana podczas tej kontroli.
Jeśli wszystkie testy zakończą się pomyślnie, napisz #
na pole gry i sprawdź, czy dotarliśmy do miejsca docelowego.
Jeśli tak, napisz ostatnią ścieżkę i wyjdź.
W przeciwnym razie zapisz współrzędne na stosie ze 1
znacznikiem typu do późniejszego cofnięcia.
Jest to przerywane obliczaniem liczb losowych, które wkrótce będziemy potrzebować.
Wciśnij cztery potencjalne miejsca docelowe, do których można dotrzeć z bieżącej lokalizacji. Liczba losowa określa kolejność ich wypychania, a tym samym kolejność, w jakiej będą przestrzegane.
Zawiń z powrotem na początek głównej pętli i przetwarzaj kolejne wartości na stosie.