Labirynt , 394 386 bajtów
Z dumą przedstawiam ...
<}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111
? @
:" }}_47}_95 3""""""""(
_ : } _ } {=}
2 23_}29_ _ ; : \
0 ; 3 +_( 3_" 60{ .{.{.
"-_95:}}"" 2 0 ) 2 " _ _ {
"" _ : 2 _ ."(; } 3 .{
;_92}_47} : _ 0 = : * ;
: "" 2 {.{{ . -""(
}}:59_}}:::: "";_ . { _ "
} " {.{.{. 32.
}}}_95:}}}}_20-
... mój nowy dwuwymiarowy esolang Labirynt! Powyższy kod nie jest niewiarygodnie dobrze golfowy (jest 161 pól i 25 NOP, więc lepszy układ może to znacznie skrócić), ale przynajmniej udało mi się pokazać, że język nadaje się do zadań niebanalnych. :)
Jak to działa
Najpierw krótki przegląd języka:
- Labirynt działa na dwóch stosach, głównym i pomocniczym , które mogą zawierać dowolne liczby całkowite ze znakiem. Na dole obu stosów znajduje się nieskończona ilość zer.
- Polecenia to pojedyncze znaki na siatce 2D i tworzą labirynt (to znaczy nieznane postacie, zwłaszcza spacje, są ścianami).
"jest NOP, który nie jest ścianą i może być pomocny przy wypełnianiu określonych ścieżek w kodzie. W przeciwieństwie do wielu innych języków 2D krawędzie nie zawijają się.
- Wskaźnik instrukcji (IP) zaczyna się od pierwszego nie-ściennego znaku (w kolejności czytania) przesuwającego się w prawo.
@kończy program.
- Jeśli to możliwe, IP przebiega wzdłuż korytarzy (również wokół zakrętów). Jeśli adres IP ma do przejścia wiele komórek, zazwyczaj skręca w lewo, jeśli góra głównego stosu jest ujemna, poruszaj się na wprost, jeśli wynosi zero, lub skręć w prawo, jeśli jest dodatnia. Kiedy IP uderza w ścianę, odwraca kierunek. (Jest jeszcze kilka subtelności, ale nie powinny one mieć znaczenia dla tego kodu.) Jest to jedyny sposób na wdrożenie przepływu sterowania.
- Oprócz poleceń arytmetycznych i manipulacji na stosie, kod źródłowy można modyfikować w czasie wykonywania za pomocą czterech poleceń,
>v<^które cyklicznie przesuwają wiersz lub kolumnę kodu źródłowego o jedną komórkę. To, którego wiersza lub kolumny dotyczy, zależy od góry stosu. Jeśli własny wiersz lub kolumna adresu IP zostanie przesunięta, będzie się przesuwać wraz z przesunięciem. Umożliwia to przeskakiwanie z jednej krawędzi kodu źródłowego na drugą.
Teraz, w przypadku tego konkretnego wyzwania, oto ogólna idea algorytmu:
- Dociśnij końce samochodów do czapek (tj.
/ \_o oo o) Na stos pomocniczy.
- Przeczytaj dane wejściowe i określ, czy naciskać,
__czy /\dalej.
- Wciśnij resztę samochodów (tj.
__ __ _/ \Dwie spacje wiodące) na stos pomocniczy.
- Zablokuj wejście do maksymalnej wartości
20, nazwijmy to N .
- Teraz wykonaj następujące 3 razy:
- Wydrukuj N spacji.
- Wydrukuj 6 zapisanych znaków.
- Wydrukuj 60-3 * N spacji.
- Wydrukuj 6 zapisanych znaków.
- Wydrukuj nowy wiersz.
Na koniec spójrzmy na niektóre części kodu. Adres IP zaczyna się w lewym górnym rogu, za pomocą polecenia przesunięcia siatki. Góra głównego stosu jest 0(która jest używana jako indeks względny), więc pierwszy rząd jest przesunięty w lewo, co również przesuwa IP na prawy koniec siatki. Teraz pierwszy rząd jest po prostu wykonywany od prawej do lewej, co wypycha pierwszy zestaw stałych znaków na stos pomocniczy:
}74}}:23}29}59}}}}}}}:111_}}}}:::::::23_}:111<
To przesunięcie wiersza jest przydatne podczas gry w golfa, gdy chcesz zacząć od dużej ilości kodu liniowego.
Następnie czytamy dane wejściowe i wciskamy odpowiednie maski:
?
:"
_
2
0 ;
"-_95:}}""
"" _
;_92}_47}
Bit po lewej z trzema NOP wysyła negatywne wyniki wzdłuż górnej gałęzi i nieujemne wyniki wzdłuż dolnej gałęzi. Po prawej są ponownie połączone.
Teraz następuje kolejna duża sekcja liniowa (która prawdopodobnie mogłaby być często golfa z inną sztuczką polegającą na przesuwaniu rzędów):
}}_47}_95
: }
23_}29_ _
3
2
:
:
:
}}:59_}}::::
}
}}}_95:}}}}
Spycha to resztę samochodów na stos pomocniczy.
Następnie obliczamy min(20, input), która jest podobna do pierwszej gałęzi:
;
+_(
0 )
2 _
_ 0
"" 2
"";_
"
_20-
Wreszcie mamy pętlę, która działa trzy razy, aby wydrukować linie. Każda iteracja pętli zawiera dwie małe (3x3) pętle do drukowania spacji, a także dwie sekcje do drukowania 6 znaków ze stosu pomocniczego:
@
3""""""""(
_ } {=}
: \
3_" 60{ .{.{.
2 " _ _ {
."(; } 3 .{
= : * ;
{.{{ . -""(
. { _ "
{.{.{. 32.
Jedną fajną sztuczką, na którą chciałbym zwrócić uwagę, jest .{.{.jej prawy brzeg. Jest to ślepy zaułek, więc poza .końcem kod jest wykonywany dwukrotnie, raz do przodu i raz do tyłu. Daje to dobry sposób na skrócenie kodu palindromicznego (haczyk polega na tym, że musisz upewnić się, że IP przybiera prawidłowy obrót przy ponownym wyjściu z ślepej uliczki).
/ \a nie spadające_ _?