To wyzwanie jest nagrodą dla ais523 za zwycięstwo w kategorii „ Świeżak roku ” w „ Best of PPCG 2016 ”. Gratulacje!
BackFlip to ezoteryczny język programowania stworzony przez użytkownika ais523 , który stworzył ponad 30 innych interesujących esolangów .
BackFlip to język 2D, taki jak Befunge lub > <>, w którym wskaźnik instrukcji przemierza siatkę tekstu (program), poruszając się w górę, w dół, w lewo i w prawo, zmieniając kierunek w zależności od znaku, na którym jest ustawiony. Krytycznie siatka w programie BackFlip zmienia się w trakcie ruchu, trochę jak Ant Langtona .
W przypadku tego wyzwania można założyć, że program BackFlip jest zawsze prostokątną siatką tekstu (wszystkie linie tej samej długości) o rozmiarze co najmniej 1 × 1, zawierającym tylko znaki ./\<>^V
. ( .
służy do widoczności, a nie do przestrzeni.) Semantycznie BackFlip, którego tu użyjemy, jest identyczny z oryginalną specyfikacją .
Wskaźnik instrukcji (IP) w BackFlip zawsze zaczyna się na lewo od lewego górnego rogu programu, na prawo. Istnieją trzy rodzaje poleceń, które może napotkać:
.
jest zakazem. IP kontynuuje w kierunku, w którym zmierza. No-op pozostaje no-op./
i\
są zwierciadłami. Odbijają IP w kierunku wskazanym przez ich kąt, a następnie zmieniają się w inny rodzaj lustra .- Na przykład, jeśli IP zmierza w lewo
\
, zaczyna przesuwać się w górę zamiast w lewo i\
staje się/
.
- Na przykład, jeśli IP zmierza w lewo
<
,>
,^
, IV
są strzałkami. Przekierowują adres IP w kierunku, w którym wskazują, a następnie zmieniają się w strzałkę wskazującą kierunek, z którego pochodzi adres IP (przeciwnie do kierunku, w którym poruszał się adres IP) .- Na przykład, jeśli IP zmierza w dół
>
, zaczyna się przesuwać w prawo zamiast w dół i>
staje się,^
ponieważ jest to kierunek, z którego pochodzi IP.
- Na przykład, jeśli IP zmierza w dół
Program BackFlip kończy się, gdy IP wykracza poza granice, tzn. Znika z siatki. Okazuje się, że wszystkie programy BackFlip ostatecznie się kończą, ponieważ nieskończone pętle są niemożliwe. (Możesz założyć, że to prawda).
Twoim celem w tym wyzwaniu jest napisanie programu lub funkcji, która pobierze program BackFlip i wyświetli liczbę ruchów, jakie wskaźnik instrukcji wykona przed zakończeniem programu. To znaczy, ile kroków wykonuje IP w trakcie uruchamiania programu? Obejmuje to wstępny krok na siatkę i ostatni krok z niej.
Na przykład wskaźnik instrukcji wykonuje 5 kroków w trywialnej siatce ....
:
.... <- empty 4×1 grid
012345 <- step number of the IP
Więc wyjściem ....
jest 5
.
W bardziej złożonej siatce 4 × 2
\...
\.><
IP opuszcza siatkę na 9 kroku, więc wynik jest następujący 9
:
step grid IP position (@)
0 \... @....
\.>< ....
1 \... @...
\.>< ....
2 /... ....
\.>< @...
3 /... ....
/.>< .@..
4 /... ....
/.>< ..@.
5 /... ....
/.<< ...@
6 /... ....
/.<< ..@.
7 /... ....
/.>< .@..
8 /... ....
/.>< @...
9 /... ....
\.>< ....
@
Najkrótszy kod w bajtach wygrywa.
W razie potrzeby dane wejściowe można traktować jako tablicę wierszy lub macierzy znaków zamiast ciągu wielowierszowego, ale należy użyć tych znaków ./\<>^V
(nie liczb całkowitych). Możesz użyć spacji zamiast, .
jeśli wolisz. W porządku, jeśli takie znaki \
wymagają zmiany znaczenia na wejściu. Wyjście jest zawsze liczbą całkowitą więcej niż jedną.
Przypadki testowe
....
5
\...
\.><
9
.
2
..
3
.
.
2
\
2
^
2
.^.
3
<.
2
\\
\/
7
>V
^<
6
>\
>/
6
\><
2
\><
\><
7
\><
\><
\><
12
\.V.
\.\<
5
\.V.
\./<
9
V./\
V./\
>./<
..\/
14
\V..
.^..
\/><
.V..
.^..
20
\.V.V.
\./.\<
.>\<..
..^.^.
31
\.V.V.V.
\./>/.\<
.>\>\<..
..^.^.^.
69
\.V.V.V.V.
\./>/>/.\<
.>\>\>\<..
..^.^.^.^.
145
\.V.V.V.V.V.V.V.V.V.V.
\./>/>/>/>/>/>/>/>/.\<
.>\>\>\>\>\>\>\>\>\<..
..^.^.^.^.^.^.^.^.^.^.
9721
źródło
/
spowoduje, że IP wzrośnie, a skierowanie do góry/
sprawi, że IP pójdzie w prawo, jakby to była piłka odbijająca się od ściany. (Ale pamiętaj o/
zmianach w odwrotnym ukośniku po tym, jak IP ich dotknie.)Odpowiedzi:
JavaScript (ES6), 158 bajtów
Opracowany niezależnie od odpowiedzi @ tsh, choć uderzająco podobny.
Odwzorowanie kierunków
^<v>
na liczby całkowite 0-3 jest regulowane przez fakt, że.search('^')
zwraca 0, ponieważ^
jest metaznakiem wyrażenia regularnego.źródło
Haskell ,
333325 bajtówEDYTOWAĆ:
f
Usprawniono punkt i scalonob
.b
pobiera listęString
s i zwraca anInteger
.Wypróbuj online!
Jak to działa
C a
jest wykorzystywanym typem danych, ponieważ Haskell nie zezwoli na rekurencję typu bez wyraźnego zadeklarowania go.C
jest także konstruktorem opakowującym ic
jest odpowiednią funkcją rozpakowywania. Jest używany tylko za=[Int]
.C [Int]
reprezentuje polecenie komórkowe, jako funkcję, która przyjmuje[Int]
argument direction ( ) i zwraca parę nowego kierunku i nowejC [Int]
wartości.b
jest główną funkcją. Konwertuje każdy znak naC
wartość, a następnie wywołuje#
.g
to siatka jako lista ciągów znaków.\
należy uciec i jest to najdłuższy znak do wspomnienia, jego wynik jest zamiast tego używany jako wartość domyślna dla wyszukiwania listy.#
uruchamia główną symulację, sprawdzając granice&
i generując nowe siatki za pomocą?
.[y,x]
jest bieżącą pozycją,d
bieżącym kierunkiem ig
bieżącą siatką.[f,e]
jest kolejnym kierunkiem in
składa się z pary i następnej siatki.l&i
sprawdza, czy indeksi
jest poza zakresem dla listyl
. (WracaTrue
poza boisko, ponieważ pozwala to uniknąć manekina wartownika#
.)f(l!!i)==(d,x)
,(f?i)l==(d,m)
gdziem
jest listal
zi
elementem th zamienionym nax
.(?i)
jest bardziej ogólnym obiektywem, skupiającym się na i-tym elemencie listy, w tym przypadku używanym z(,) [Int]
instancją funktora.n
to funkcja reprezentująca kropkę.a v
to funkcja reprezentująca strzałkę w kierunkuv
.m s
jest funkcją reprezentującą lustro;s==1
za\\
is==-1
za/
.źródło
JavaScript, 172 bajty
Ale nie mogę przetestować ostatniej skrzynki testowej, ponieważ mam przepełnienie stosu na moim komputerze. (powinien działać, jeśli istnieje maszyna z większym tłokiem)
Używamy numeru do kierowania:
Niech
d
będzie numerem kierunku ...Pozwolić
(x, y)
być aktualna pozycja, następna pozycja to:x+(t&1&&t-2)
,y+(~t&1&&t-1)
Uwaga:
Funkcja przyjmuje jeden parametr o następującym formacie:
Sprawdź to tutaj
źródło
Uncaught RangeError: Maximum call stack size exceeded
16 GB pamięci RAM.var
deklaracje sprawiają, że przechodzi on ostatnią próbę (interpreter js optymalizuje wywołanie ogonowe w trybie ścisłym)C,
232221 bajtówPobiera dane wejściowe w pierwszym argumencie, wyświetla wynik. Wymaga, aby dane wejściowe zawierały co najmniej 1 nową linię (więc jeśli jest tylko 1 wiersz, musi kończyć się nową linią)
Przykładowe użycie:
Awaria:
źródło
Python 3 , 286 bajtów
[f () przyjmuje dane wejściowe w postaci,
{(0,0):'/',(0,1):'.'}
więc napisałem również funkcję g () do konwersji tablicy linii do tej postaci]Wypróbuj online!
źródło