tło
Większość edytorów tekstu (w połowie przyzwoitych) pozwala nawigować po tekście za pomocą klawiszy strzałek. W górę i w dół pozwalają nawigować po liniach, podczas gdy w lewo i w prawo poruszają się po linii, ale także obejmują. Ponadto, jeśli linia jest krótsza niż pozycja X kursora, kursor pojawia się na końcu linii, ale wraca do tej samej pozycji X, jeśli poruszasz się w górę lub w dół. Być może pomocne będą następujące wyjaśnienia wizualne:
Przykłady ruchu
Prosta próbka tekstu może wyglądać tak. Kursor zostanie wstawiony między dwoma znakami w tym tekście lub na końcu.
-----
---
------
let's put the cursor here:
X-----
---
------
move down (v):
-----
X---
------
move left (<):
-----X
---
------
v
-----
---X
------
v (notice how the X position of the cursor has been maintained)
-----
---
-----X-
^
-----
---X
------
> (more line wrapping)
-----
---
X------
<
-----
---X
------
^ (the X-position from earlier is no longer maintained due to the left-right motion)
---X--
---
------
Wyzwanie
Biorąc pod uwagę kilka wierszy testu ASCII, znajdź najkrótszą ścieżkę od lokalizacji początkowej do końcowej. Lokalizacja początkowa jest reprezentowana przez, ^
a lokalizacja końcowa jest reprezentowana przez $
, i będzie tylko jedna z nich. Nie są one uważane za część tekstu i nie wpływają na „długość” tego wiersza.
Dane wejściowe będą składały się z kilku niepustych wierszy tekstu. Wyjście będzie serią ^v<>
znaków, które pokazują jedną z najkrótszych ścieżek. Opcjonalnie możesz założyć dodatkowy nowy wiersz na końcu każdego, ale nie jest on zawarty w tekście nawigacyjnym.
Możesz napisać program lub nazwaną funkcję. Zwycięzcą zostanie zgłoszenie najkrótsze, mierzone w bajtach.
Przykład I / O
^Squares
are
fun$ny
vv<v (which is better than the naive vv>>>)
Squares
^are
funny$
<vv
Alp$habet^
Song
v<^
Mary had a little lamb,
His fleece was white as snow,
And$ everywhere that ^Mary went,
The lamb was sure to go.
^^>>>>v>>>
$^degenerate case
(no output)
v<vv
, prawda? A może skończy się to po ostatnim znaku w tej linii?Odpowiedzi:
CJam, 139 bajtów
Cóż, zajęło to wiele godzin, aby dojść do czegoś, co wydaje się zrobione. Wydaje się, że czas potrzebny do agresywnej optymalizacji kodu CJam jest większy niż O (n) w odniesieniu do rozmiaru kodu ...
Możesz wypróbować go w trybie online , ale dla każdego wejścia, dla którego najlepsza ścieżka to co najmniej 6 operacji, prawdopodobnie powinieneś spróbować w trybie offline z szybszym tłumaczem.
Squished:
Rozszerzony i skomentowany:
Ogólnie rzecz biorąc, jest to dość proste rozwiązanie. „Wykonuje” cyfry reprezentacji base-5 numeru ścieżki, która jest zwiększana przy każdej iteracji, zaczynając od 0, aż ścieżka zadziała. Cyfry
1
-4
odwzorowują operacje w górę, w dół, w lewo i w prawo i0
nic nie robią. Pierwsza iteracja wykorzystująca ścieżkę po prostu0
chwyta zdegenerowany przypadek. Wszystkie inne ścieżki zawierające0
nigdy nie są wybierane, ponieważ są tylko wersjami już przetestowanych ścieżek z dodanymi opcjami.Stan jest modelowany w możliwie minimalistyczny sposób: tekst z usuniętymi znacznikami początkowym i końcowym, pozycja kursora w tekście oraz „pamięć kolumny”. Znaki nowej linii są w większości traktowane jak każdy inny znak, więc nie ma pojęcia o wierszu, a pozycja kursora jest tylko indeksem. To sprawia, że poruszanie się w lewo i w prawo jest bardzo proste, które są po prostu zaimplementowane jako zmniejszanie i zwiększanie (z mocowaniem do rozmiaru tekstu). Poruszanie się w górę i w dół jest nieco trudniejsze, ale nadal możliwe do opanowania.
Ponowne użycie kodu było dość istotną taktyką optymalizacyjną. Przykłady tego obejmują:
5
operacji zastępczej na początku ciągu ścieżki, co również zdarza się, że używa0
logiki no-op ze względu na indeksowanie macierzy cyklicznej i tylko 5 zdefiniowanych operacji.Ogólnie jestem bardzo zadowolony z tego, jak to wyszło. To zdecydowanie jak dotąd najwięcej pracy, jaką włożyłem w odpowiedź na kod do golfa (coś, co pasuje do tweeta !?). Czas działania jest jednak dość fatalny. CJam nie jest na początku najszybszym językiem, a ten algorytm ma złożoność czegoś takiego jak O (m * 5 n ) , gdzie m jest wielkością wejścia, a n wielkością wyjścia. Dobra rzecz, prędkość się nie liczy!
źródło
Python 2: 446
Proste rozwiązanie. Przeprowadzam pierwsze wyszukiwanie.
t
iteruje po wszystkich różnych ścieżkach. Przekształcamt
na bazę5
, ale używam tylko wpisów, które są niezerowe.1
jest w górę,2
jest w dół,3
jest w lewo i4
ma rację.I zachować aktualną pozycję kursora w 3 zmiennych
x
,y
iz
.x
to linia,y
pozycja kolumny iz
„ukryta” pozycja kolumny, jeśli przejdziesz w górę lub w dół, a linia jest za krótka. Wiele ifs decyduje o zmianie zmiennej podczas ruchu.Wstępne przetwarzanie jest naprawdę długie, pierwsze 4 linie wykonują tylko to zadanie.
Długa próba trwa naprawdę długo. Algorytm ma złożoność O (N * 5 ^ N), gdzie N jest długością najkrótszego rozwiązania.
Zastosowanie: Wprowadź linie jako pojedynczy ciąg (linie oddzielone
\n
) jak"Alp$habet^\nSong"
źródło
CJam - 274
Brak odpowiedzi? Ok, oto jeden :)
Wypróbuj na stronie http://cjam.aditsu.net/ ... oprócz przykładu Mary lub czegoś takiego, prawdopodobnie będziesz potrzebował tłumacza Java .
źródło