To pytanie jest rozszerzeniem sprawdzania, czy słowa są izomorfami, i kopiuje pierwszą jego część, aby podać definicję izomorfu.
Dwa słowa są izomorfami, jeśli mają ten sam wzór powtarzania liter. Na przykład, zarówno ESTATE
i DUELED
mają wzórabcdca
ESTATE
DUELED
abcdca
ponieważ litery 1 i 6 są takie same, litery 3 i 5 są takie same i nic więcej. Oznacza to również, że słowa są powiązane szyfrem podstawienia, tutaj z dopasowaniem E <-> D, S <-> U, T <-> E, A <-> L
.
Biorąc pod uwagę dwa ciągi X i Y, przy czym X nie jest dłuższy niż Y, zadaniem jest ustalenie, czy istnieje podłańcuch Y, który jest izomorfem z X.
Dane wejściowe: Dwa niepuste ciągi liter od a..zA..Z, z których jeden ciąg w linii. Będzie pochodził ze standardowego wejścia.
Wyjście Podłańcuch drugiego łańcucha, który jest izomorfem z pierwszym łańcuchem, jeśli coś takiego istnieje. W przeciwnym razie wpisz „Nie!”.
Reguły Twój kod musi działać w czasie liniowym na całej długości danych wejściowych.
Wynik Twój wynik to liczba bajtów w kodzie. Wygrywa najmniej bajtów.
Przykładowe wejście i wyjście
adca
ddaddabdaabbcc
dabd
Wskazówka
Istnieje co najmniej jeden nie , że skomplikowane, szybkie i praktycznie liniowy czas rozwiązanie tego problemu.
Odpowiedzi:
Python 2,
338326323321310306297293290289280279266264259237230229226223222220219217 (260238231228225223221220218 z 0 statusem wyjścia)Algorytm jest odmianą KMP, z wykorzystaniem testu indeksowego do dopasowywania znaków. Podstawową ideą jest to, że jeśli otrzymamy niedopasowanie pozycji
X[i]
, możemy wrócić do następnego możliwego miejsca meczu zgodnie z najdłuższym sufiksem,X[:i]
który jest izomorficzny do przedrostkaX
.Pracując od lewej do prawej, przypisujemy każdemu znakowi indeks równy odległości do ostatniego poprzedniego wystąpienia tego znaku, lub jeśli nie było wcześniejszego wystąpienia, bierzemy długość bieżącego prefiksu łańcucha. Na przykład:
Aby sprawdzić, czy dwa znaki pasują do siebie, porównujemy indeksy, odpowiednio dostosowując indeksy, które są większe niż długość bieżącego (pod) łańcucha.
Algorytm KMP staje się nieco uproszczony, ponieważ nie możemy uzyskać niedopasowania pierwszego znaku.
Ten program generuje pierwsze dopasowanie, jeśli takie istnieje. Używam błędu środowiska wykonawczego, aby wyjść w przypadku dopasowania, ale kod można łatwo zmodyfikować, aby wyjść czysto kosztem niektórych bajtów.
Uwaga: Do obliczania indeksów możemy użyć
str.rfind
(w przeciwieństwie do mojego wcześniejszego podejścia ze słownikiem) i nadal mieć liniową złożoność, zakładając, żestr.rfind
zaczyna się wyszukiwanie od końca (co wydaje się jedynym rozsądnym wyborem implementacji) - dla każdego znaku w alfabecie , nigdy nie musimy dwukrotnie przechodzić przez tę samą część łańcucha, więc istnieje górna granica porównań (rozmiar alfabetu) * (rozmiar łańcucha).Ponieważ kod został dość zaciemniony w trakcie gry w golfa, oto wcześniejsze (293 bajtowe) rozwiązanie, które jest nieco łatwiejsze do odczytania:
Do
e
testów czynnościowych równoważności znaków.exec
Instrukcja przypisuje indeksy i robi pewne zmienne Initialisations. Pierwsza pętla przetwarzaX
wartości rezerwowe, a druga pętla wyszukuje ciąg znaków.Aktualizacja: Oto wersja, która kończy się czysto, kosztem jednego bajtu:
źródło
r=raw_input
vs. r =input
oszczędza 4 bajty, a pareny na wydruku kosztują tylko 3.exec
.Python 3, 401 bajtów
Nadal jest to w większości niezamierzone, ale myślę, że powinno działać. Podstawowym algorytmem jest KMP , plus dodatkowy czynnik, który ma wpływ na wielkość alfabetu (co jest w porządku, ponieważ alfabet jest stały). Innymi słowy, jest to / powinien być jeden całkowicie niepraktyczny algorytm liniowy.
Oto kilka adnotacji, które pomogą w analizie:
Do testowania możesz zastąpić
s
mniejszym alfabetem niżstring.ascii_letters
.źródło
APL (Dyalog) , 32 bajty
Jest to funkcja poprawki, która przyjmuje X jako lewy argument, a Y jako prawy argument.
Wypróbuj online!
{
…}
Anonimowa lambda gdzie⍺
i⍵
reprezentują argumenty (X i Y)⍳⍨⍺
ɩ ndex selfie X ( ɩ ndices pierwszego wystąpienia elementów X w X)⊂
załącz, abyśmy mogli wyszukać cały wzór(
…)⍳
Ɩ ndex pierwszego wystąpienia tego w…≢⍺
tally (długość) X⍵,/⍨
wszystkie podciągi tej wielkości Y (l. redukcja konkatenacji tych, ale to nie jest operacja)s←
przechowuj ws
(dla s )⍳⍨¨
ɩ ndex selfie każdego z tychteraz mamy indeks pierwszego wzorca lub 1 + liczbę wzorców, jeśli nie znaleziono dopasowania
(
…)⊃⍨
Użyj tego indeksu, aby wybrać z…⊂'No!'
załączony ciąg (tak, aby działał jako pojedynczy element)s,
z dodatkiems
źródło