Jesteś podróżnikiem przemierzającym pustynię między dwoma miastami. Nie możesz nosić wystarczającej ilości wody, aby przejść bez zatrzymywania się. To odmiana klasycznej układanki.
Zasady
Pustynia wygląda tak: siatka WxH składająca się głównie z pustej przestrzeni. Oznaczone miejsce S
to miejsce, w którym zaczynasz, E
to miejsce, w którym chcesz zakończyć, a kwadrat oznaczony liczbą N zawiera N jednostek wody. Kwadraty oznaczone .
zatrzymaną wodą.
.....................................
........S............................
.....................................
.........7...........................
.....................................
.......................3.............
.....5...............................
................................2....
.....................................
.....................................
.....................................
...............................E.....
.....................................
....................7................
.....................................
.....................................
Zaczynasz w S z 5 jednostkami wody.
Możesz nosić maksymalnie 5 jednostek wody.
Każda kolej
- przesuń o jedno pole w górę, w dół, w lewo lub w prawo,
- zużyj 1 jednostkę wody, którą nosisz,
- podnieś lub upuść pewną liczbę jednostek wody.
Obrót jest zanotowana w ten sposób: (direction)(+|-)(units of water)
, +
wskazuje jesteś podnoszenia wody, -
które spadają go.
Przykładowe zwroty:
D+0 Move Down
R+0 Move Right
D+2 Move Down, pick up two units of water.
U-1 Move Up, drop one unit of water.
Jeśli wykonasz te ruchy, zaczynając od litery S w powyższym przykładzie, pustynia będzie wyglądać później.
.....................................
........S............................
.........1...........................
.........5...........................
.....................................
.......................3.............
.....5...............................
................................2....
.....................................
.....................................
.....................................
...............................E.....
.....................................
....................7................
.....................................
.....................................
Nie możesz zebrać więcej wody niż jest na twoim placu. Kiedy podnosisz wodę, odejmij tę liczbę jednostek od liczby płytek.
Możesz zbierać wodę, aby pomieścić maksymalnie 5 jednostek.
Żaden żeton nie może pomieścić więcej niż 9 jednostek, z wyjątkiem S, która zawiera jednostki nieskończoności.
Możesz upuścić tylko tyle wody, ile aktualnie trzymasz.
Woda na ziemi pozostaje niezmieniona, dopóki nie podniesiesz jej ponownie.
Jeśli wrócisz do S, możesz zebrać dowolną ilość wody bez jej wyczerpywania.
Jeśli osiągniesz E, wtedy wygrasz . Nadal wygrywasz, jeśli spożyjesz ostatnią jednostkę wody na E.
Jeśli po swojej turze masz zero wody i nie jesteś na E, umierasz .
Wejście i wyjście
Twój program otrzyma mapę początkową o dowolnym rozmiarze STDIN
jako grafikę ASCII w powyższym formacie. Możesz założyć, że jest prostokątny, tzn. Wszystkie linie mają tę samą długość, że jest dokładnie jeden S
i jeden E
kwadrat, wszystkie linie są zakończone \n
, a cały STDIN będzie zgodny z tym wyrażeniem regularnym:/^[SE1-9\.\n]+$/
Twój program zapisze następujące dane wyjściowe do STDOUT:
- lista ruchów,
- ostateczny stan mapy.
Możesz wypisać listę ruchów w dowolnym dogodnym formacie.
Ostateczny stan mapy zostanie wydrukowany w tym samym formacie co dane wejściowe, z tym wyjątkiem, że dodatkowo pokaże trasę, którą przeszedłeś przez pustynię , zaznaczając wszystkie odwiedzane kafelki symbolem #
, jeśli ten kafelek nie zawiera wody i nie jest S ani E (tj. to jest .
).
PRZYKŁADOWE wejście:
.....S.
.......
.......
E......
....8..
PRZYKŁAD zwycięska produkcja:
D+0
D+0
D+0
D+0
L+5
L+0
L+0
L+0
L+0
U+0
.....S.
.....#.
.....#.
E....#.
####3#.
Nietrywialność
Po opublikowaniu kodu opublikuj przykładowe dane wejściowe mapy, dla których Twój kod znajdzie rozwiązanie, które spełnia następujące warunki nietrywialności:
- S i E są oddalone o co najmniej 10 ruchów.
- Każdy kwadrat, który początkowo zawiera N jednostek wody, musi być otoczony ramką o szerokości N, w której znajdują się wszystkie kwadraty
.
(bez wody, nie S lub E)
PRZYKŁAD
........2.
..........
..........
S.1..2....
..........
..........
........1.
..3.......
.........E
Jeśli zwiększysz ilość wody na dowolnym kafelku, powyższe stanie się banalne.
Wymagania
Prawdopodobnie twój program napotka szereg nieudanych prób, zanim znajdzie rozwiązanie, jeśli w ogóle.
- Twój program musi ostatecznie rozwiązać wszelkie możliwe do rozwiązania dane wejściowe.
- Chcę patrzeć, jak umierasz - twój program wyświetli ruchy i ostateczną mapę trasy na śmierć za każdą nieudaną próbę znalezienia rozwiązania.
- Jeśli napotkasz zwycięskie rozwiązanie, wydrukuj dla niego pełne wyjście i zakończ.
- Biegaj, aż znajdziesz rozwiązanie, ale nie próbuj dwukrotnie tego samego rozwiązania - wszystkie zgony powinny odbywać się różnymi drogami.
- Użyj tego wejścia testowego:
(wymaga co najmniej jednego ruchu, aby upuścić bufor wody w pewnym punkcie środkowym).
S........
.........
.........
........E
Najkrótszy kod, który jest opublikowany z nietrywialnym wejściem demonstracyjnym, który rozwiązuje, wygrywa.
Odpowiedzi:
Perl,
299 + 1 = 300254 + 1 = 255 bajtówTo prawie na pewno zostanie pokonane przez jeden z języków gry w golfa, gdy ludzie zobaczą mój algorytm :-)
Uruchom z
-n
(1 bajtowa kara).Poprzednia wersja nie była w pełni zgodna ze specyfikacją, ponieważ pozostawiała dodatkową wodę na mapie i nie pokazywała jej w ostatecznej wersji mapy; zmieniając algorytm, aby poradzić sobie z tą sytuacją, udało mi się w ten sposób nieco pomniejszyć.
Przykład (dodałem podziały wiersza do danych wyjściowych, aby uniknąć potrzeby przewijania i wyświetlania struktury):
W notacji używane przez program, ruch jest reprezentowany przez
L
,R
,U
, iD
na lewo, w górę, w prawo, w dół odpowiednio. Domyślnie po każdym ruchu zbierasz 1 jednostkę wody, ale można to zmienić, dodając postać:X
: upuść 2 jednostki wody zamiast zbierać 1Y
: upuść 1 jednostkę wody zamiast zbierać 1(tj. spacja): całkowicie uzupełnij wodę (wypływa dopiero po przejściu do
S
; program wypisuje również spację wiodącą, co ma sens, ponieważ zaczynasz napełniać się wodą)Jak widać, możliwe jest przekroczenie tej (raczej jałowej) mapy bez żadnych dodatkowych pul. W rzeczywistości można uzyskać dowolną odległość na podstawie tych zasad, na dowolnej mapie, bez pomocy wcześniej umieszczonej wody. Jako taki, ten algorytm po prostu ignoruje wstępnie umieszczoną wodę, co oznacza, że nie muszę marnować bajtów próbując sobie z tym poradzić. Oznacza to również, że nie zobaczysz bota umierającego, przepraszam. Nigdy nie wychodzi poza zasięg, w którym wie, że na pewno przetrwa.
Powodem musimy zarówno
X
iY
(i trochę dodatkowego kodu, aby upewnić się, mamyX
w większości strategii, ale od czasu do czasuY
na końcu) jest to, że specyfikacja wymaga ostateczną wersję mapy na wyjściu. Najłatwiejszym sposobem na to jest pozostawienie mapy nietkniętej (poza naszą ścieżką przez początkowo puste kwadraty), zwłaszcza, że kwadrat, który zaczynał się od9
wody, skończyłby10
(łamaniem sztuki ASCII), gdyby trafił na ścieżkę i użyliśmy tylkoX
i dlatego musimy znaleźć rozwiązanie, które pozwoli uniknąć zrzucania dodatkowej wody na mapę. Algorytm „naturalnie” zrzuciłby 1 dodatkową jednostkę wody na każdy kwadrat na trasie; dlatego przedostatni czas, jaki odwiedzamy na każdym placu, zmniejszamy ilość wody upuszczonej o 1 za pomocą Y zamiast X, więc podczas naszej ostatniej wizyty spuszczamy kwadrat z powrotem do pierwotnej ilości wody, a nie pozostawiając go nieco bardziej wilgotnego niż na początku.Odradzam uruchamianie tego na dużej mapie, ponieważ ma on wydajność O (2 ^ n) (chociaż bot nigdy nie umiera z pragnienia, można przypuszczać, że przy takiej strategii umrze z głodu).
Wersja do odczytu:
źródło