Twoim zadaniem jest napisanie interpretera RoboZZle. Jeśli nie znasz gry, obejrzyj wideo na robozzle.com lub przeczytaj mój opis poniżej.
Robot żyje na prostokątnej siatce kwadratów w kolorze czerwonym, zielonym, niebieskim lub czarnym. Czarne kwadraty są niedostępne. Inne są dostępne, a niektóre z nich zawierają gwiazdkę. Celem jest zebranie wszystkich gwiazd bez wchodzenia na czarne kwadraty i spadania z mapy. Robot zajmuje jeden kwadrat i jest skierowany w określonym kierunku - w lewo, w prawo, w górę lub w dół. Postępuje zgodnie z instrukcjami podobnymi do złożenia pogrupowanymi w podprogramy F1, F2, ..., F5. Instrukcja jest parą predykatu („brak”, „jeśli na czerwonym”, „jeśli na zielonym”, „jeśli na niebieskim”) i akcja („idź do przodu”, „skręć w lewo”, „skręć w prawo”, „pomaluj bieżący kwadrat na czerwono”, „pomaluj na zielono”, „pomaluj na niebiesko”, „nic nie rób”, „zadzwoń do F1”, ..., „zadzwoń do F5”). Wywołania podprogramów używają stosu i mogą być rekurencyjne. Podobnie jak w konwencjonalnym programowaniu, po zakończeniu ostatniej instrukcji podprogramu wykonywanie jest kontynuowane od momentu wywołania podprogramu. Wykonanie rozpoczyna się od pierwszej instrukcji F1 i trwa do momentu, gdy robot odwiedzi wszystkie kwadraty z gwiazdami lub gdy robot wejdzie na czarny kwadrat lub poza mapę, lub wykona 1000 instrukcji (nieudane predykaty i akcje „nic nie rób”) nie licz) lub nie ma już instrukcji do wykonania (niedopełnienie stosu).
Wejścia:
a
- matryca 12 x 16 znaków (jak zwykle reprezentowana w twoim języku, np. tablica ciągów znaków), która koduje mapę -'#'
dla niedostępnych (czarnych) kwadratów,'*'
dla kwadratów z gwiazdą,'.'
dla resztyc
- matryca znaków 12x16 opisująca kolory dostępnych kwadratów -'R'
(czerwony),'G'
(zielony) lub'B'
(niebieski). Niedostępne kwadraty będą reprezentowane przez dowolną literę z trzech.y
orazx
- wiersz i kolumna robota oparte na 0;a[y][x]
gwarantowane jest'.'
d
- kierunek robota stoi:0 1 2 3
na prawo, w dół, w lewo, w górę, czyli w kierunku(y,x+1)
,(y+1,x)
,(y,x-1)
,(y-1,x)
f
- pojedynczy ciąg, połączone implementacje F1 ... F5. Każda implementacja to (być może pusta) sekwencja par predykat-akcja (maksymalnie 10 par na podprogram), zakończona znakiem'|'
.predykaty:
'_'
brak,'r'
czerwony,'g'
zielony,'b'
niebieskiakcje:
'F'
idź do przodu,'L'
skręć w lewo,'R'
skręć w prawo,'r'
pomaluj na czerwono,'g'
pomaluj na zielono,'b'
pomaluj na niebiesko,'1'
zadzwoń do F1, ...,'5'
zadzwoń do F5,'_'
nic nie rób
Nie musisz nazywać swoich danych wejściowych jak wyżej, ale ich wartości muszą być zgodne z podanymi.
Wyjście: 1
(lub true
) jeśli robot zbiera wszystkie gwiazdy zgodnie z zasadami, 0
( false
) w przeciwnym razie.
Przykład :
a=["################","################","##*....*...*#.##","##.####.#####.##","##.####.#####.##","##.####*...*#.##","##.########.####","##*........*#.##","################","################","################","################"]
c=["RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRBBBBRGGGGRRRR","RRBRRRRGRRRRRRRR","RRBRRRRGRRRRRRRR","RRBRRRRRGGGBRRRR","RRBRRRRRRRRGRRRR","RRRBBBBGGGGBRBRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR","RRRRRRRRRRRRRRRR"]
y=2; x=6; d=2
// and then depending on "f":
f="_FrLg2_1|_FbLrR_2||||" // result:1
f="_FrRg2_1|_FbLrR_2||||" // result:0 (stepped on a black square)
f="_FrLrL_1|_FbLrR_2||||" // result:0 (1000-step limit exceeded)
f="_FrLg2__|________||||" // result:0 (stack underflow)
Kolejny przykład dotyczący instrukcji „malowania”:
a=["#***************","#*###*###*###*##","#*###*###*###*##","***#***#***#***#","***#***#***#***#","*###*###*###*###","***#***#***#***#","***#***#***#***#","***#***#***#***#","*###*###*###*###","*.*#***#***#***#","***#***#***#***#"]
c=["RGGGGGGGGGGGGGGG","RBRRRGRRRGRRRGRR","RBRRRGRRRGRRRGRR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BRRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR","BRRRGGGRGGGRGGGR","BRRRGRRRGRRRGRRR","BGRRGGGRGGGRGGGR","RBRRGGGRGGGRGGGR"]
y=10; x=1; d=0
f="_2_R_R_1|_FgRgFgFg3rRr4b2_Fgb|_F_F_R|_2_L_r||"
// result:1
Aby wygenerować własny test, przejdź do układanki z listy na stronie robozzle.com , spróbuj ją rozwiązać (lub nie rozwiązać), naciśnij F12 w przeglądarce, wpisz w konsoli JS:
r=robozzle;s=JSON.stringify;with(r.level)console.log('a='+s(Items)+'\nc='+s(Colors)+'\ny='+RobotRow+'\nx='+RobotCol+'\nd='+RobotDir+'\nf='+s(r.encodeSolution()))
i ponownie sformatuj wynik dla swojego języka.
Najkrótsze wygrane. Bez luk.
Odpowiedzi:
Prolog (SWI) , 574 bajty
Wypróbuj online!
Definiuje to predykat, który po wywołaniu powiedzie się, jeśli wszystkie gwiazdy zostaną pomyślnie zebrane, a inaczej nie powiedzie się. Orzecznik bierze argumenty takie jak:
a+c+f+x^y^d.
.a
ic
muszą być listami ciągów cytowanych wstecznie, podczas gdyf
muszą być ciągami podwójnie cytowanymi.Wyjaśnienie
Ten program zawiera trzy predykaty,
*/2
,^/2
, i+/2
. W*/2
orzeczniki który określa się na pierwszej linii odpowiada za część przetwarzania sygnału.^/2
Orzecznik rekurencyjnie oblicza jak robot porusza się krok po kroku, a jeśli uda robot prawnie zbiera wszystkie gwiazdy i nie inaczej.+/2
Orzecznikiem jest głównym orzecznikiem programu i przygotowuje wejście do^/2
orzecznika z jakiejś pomocy od*/2
orzecznika. Zauważ, że każdy z tych predykatów technicznie wymaga tylko dwóch argumentów, ale używając operatorów i dopasowywania wzorców, mogą zachowywać się tak, jakby mieli więcej argumentów (omawiam to zjawisko bardziej szczegółowo tutaj ).*/2
Ten predykat przyjmuje dwa argumenty. Pierwsza to lista kodów znaków (w ten sposób Prolog analizuje ciągi cudzysłowu). Drugi to mapa asocjacyjna od punktów na mapie 12x16 (reprezentowanych jako
X^Y
) do 32 plus kod znaku zapisany w tym punkcie na liście list kodów znaków. 32 jest dodawany do każdego z kodów znaków, dzięki czemu w matrycy kolorów zamieni wielkie i kolorowe litery na małe.W ten sposób generuje listę par punktów i kodów znaków w tym punkcie, używając
findall/3
. Następnie używalist_to_assoc/2
do utworzenia odpowiedniej mapy asocjacyjnej z punktów do kodu znaku w tym punkcie.findall/3
Orzecznikiem jest wbudowane wykonuje „szablon” jako pierwszy argument, cel jako drugi argument i listy jako jej trzeci argument. Predykat wypełnia listę wszystkimi możliwymi wartościami szablonu, które powodują sukces celu. Ze względu na pierwszeństwo operatora, szablon, który jest przekazywany dofindall/3
w*/2
jest analizowany jako(X^Y)-D
.-
Operator reprezentuje parę dwóch wartości w Prologu więc szablon reprezentuje położenie punktu w (X^Y
) w połączeniu z 32 plus point SA kodem znaków (D
). Zauważ, że^
użyte w reprezentacji punktu nie jest w żaden sposób związane z^/2
predykatem.Rozważmy cel, który jest przekazywany do
findall/3
orzeczenia.Cel zawiera trzy predykaty, z których każdy musi się powieść, aby cel się powiódł.
nth0/3
Orzecznikiem, który jest używany dwa razy jest używany, aby uzyskać wartość w określonym indeksem liście (0
w nazwie wskazuje, że jest zerem indeksowane). Pierwsze wywołanie do niego przechowujeY
th wiersz macierzy znaków w,O
podczas gdy drugie wywołanie przechowujeX
th znak w tym rzędzie wC
. Ostateczny predykat sięplus/3
powiedzie, jeśli jego dwa pierwsze argumenty sumują się z trzecim argumentem. Służy to do tego, aby kod znaku w parze był 32 większy niż kod znaku w matrycy znaków, który, jak wspomniano powyżej, zamieni wszystkie wielkie litery na małe.Na koniec
findall/3
przechowuje wszystkieX^Y-D
kombinacje, które powodują, że jego cel odnosi sukces na liście, zL
której zbudowana jest mapa asocjacyjna.Więcej wkrótce...
źródło
JavaScript (ES6),
298276264 bajtówZaoszczędzono 8 bajtów dzięki @ngn
Pobiera dane wejściowe jako
(a,c,x,y,d,f)
, gdziea
ic
są tablicami tablic znaków. Zwraca0
lub1
.Przypadki testowe
Pokaż fragment kodu
Skomentował
źródło
x+='2101'[d&3]-1,y+='1210'[d&3]-1
->d&=3,x+=(1-d)%2,y+=(2-d)%2
x
zmienia się co najwyżej o 1, więc myślę, że można zastąpićx&~15
zx&16
APL (Dyalog Classic) ,
236233 bajtów-3 dzięki Erikowi Outgolfer
Teraz, gdy rozdałem bonus, zamieszczam przykładowe rozwiązanie mojego własnego wyzwania. Jest tu miejsce na ulepszenia - zachęcamy do kopiowania i gry w golfa dalej.
Wypróbuj online!
Taki sam jak powyżej, rozszerzony o komentarze:
źródło