Każdy krok odległości Levenshtein

18

W tym wyzwaniu napiszesz program, który przyjmuje dwa ciągi oddzielone znakiem nowej linii, s1 (pierwszy wiersz) i s2 (drugi wiersz) jako dane wejściowe (STDIN lub najbliższy). Możesz założyć, że długość s1 będzie zawsze mniejsza niż 30 i większa niż długość s2. Program powinien następnie wypisywać każdy krok w odległości levenshteina od s1 do s2.

Aby wyjaśnić, co oznacza każdy krok w odległości levenshtein, program wydrukuje n łańcuchów, gdzie n jest odległością levenshtein między s1 i s2, a odległość lewenshteina między dwoma sąsiednimi łańcuchami będzie zawsze równa jeden. Kolejność nie ma znaczenia. Dane wyjściowe powinny być oddzielone znakiem nowej linii i nie mogą zawierać s1, a tylko między nimi i s2. Program powinien również działać w niecałą minutę na nowoczesnym komputerze.

Przykłady:

Wejście:

Programming
Codegolf

Wynik:

rogramming
Cogramming
Coramming
Coamming
Codmming
Codeming
Codeging
Codegong
Codegolg
Codegolf

Wejście:

Questions
Answers

Wynik:

uestions
Aestions
Anstions
Ansions
Answons
Answens
Answers

Wejście:

Offline
Online

Wynik:

Ofline
Online

Wejście:

Saturday
Sunday

Wynik:

Sturday
Surday
Sunday

Oto link do skryptu Pythona, który drukuje odległość i kroki.

Dodatkowe zasady:

To jest golf golfowy, więc kod powinien być krótki; najkrótszy kod wygrywa!

Loovjo
źródło
1
Do mojej edycji raczej zakładałem, że dane wejściowe będą miały postać s1(newline)s2, jednak po ponownym przejrzeniu pytania zastanawiam się, czy zamiast tego zamierzałeś, aby program wybrał s1 i s2 na podstawie długości 2 wprowadzonych ciągów w dowolnej kolejności, czy mógłbyś wyjaśnić tę kwestię? To znaczy, czy zakładamy, że wejście to s1, po którym następuje s2, czy też wybieramy s1 i s2 na podstawie długości dwóch wejść?
VisualMelon,
Czy odpowiedź musi zostać udzielona w rozsądnym czasie?
KSab,
Camper - Amper, odległość 2, skrypt Pythona działa wiecznie ...
edc65
Jak surowe jest „pobieranie danych z STDIN lub najbliższych”? Czy mogę napisać funkcję, która pobiera dane wejściowe za pomocą argumentu funkcji? Tak jest w przypadku obecnie akceptowanej odpowiedzi.
nimi

Odpowiedzi:

4

JavaScript, 167 161 154 bajty

function l(a,b,d){if(a!=b){if(a[l="length"]>b[l])a=a[s="slice"](1),d=-1;else if(a[d]!=b[d])a=a[s](0,d)+b[d]+a[s](d+1);document.write(a+"<p>");l(a,b,++d)}}

Zadzwoń z l("Programming","golf")

Codepen

Odtłuszczony (i opatrzony adnotacjami) kod (nieaktualny, ale masz pomysł):

function l(a, b, d) {
  s = "substring"; //saving this to a string lets us call it with a[s] later
  if (a != b) { //if the strings aren't the same, continue
    if (a.length > b.length) { //if a is still greater than b we can delete characters
      a = a[s](1); //delete the first character from a
      d = -1 //when we start swapping characters, we'll need d to start at 0
    } else if (a[d] != b[d]) { //if the d'th character isn't the same, we can swap them
      a = a[s](0, d) + b[d] + a[s](d + 1) //swap the d'th character of b into a
    }
    document.write(a + "<p>"); //the first call to document.write overwrites the page but successive calls append the output 
    l(a, b, ++d) //increment d and recurse
  }
}
9999 lat
źródło
funkcja l (a, b, d) {s = "plasterek"; if (a! = b) {if (a. długość> b. długość) a = a [s] (1), d = -1; else if (a [d]! = b [d]) a = a [s] (0, d) + b [d] + a [s] (d + 1); document.write (a + "<p>" ); l (a, b, ++ d)}}
Dr. Pain
@nimi: Jeśli wywołasz go z dwoma argumentami (np. l („programowanie”, „codegolf”)), to działa tak samo, więc przypuszczam, że twój punkt jest zerowy.
9999 lat
Również zadeklarowanie swewnątrz a=a[s](1)jako a=a[s="slice"](1)oszczędza niektóre bajty.
Mama Fun Roll
1
Zgodnie z linkiem do codepen, twój program generuje 11 kroków dla "Programming"-> "Codegolf", ale powinno to być 10.
nimi
10

Haskell, 201 194 bajtów

l=length
g[]n u=map(\_->"")n
g(b:c)[]u=(u++c):g c[]u
g(b:c)n@(o:p)u|b==o=g c p(u++[o])|1<2=((u++o:c):g c p(u++[o]))!((u++c):g c n u)
a!b|l a<l b=a|1<2=b
p[a,n]=g a n""
f=interact$unlines.p.lines

Dłuższy niż oczekiwano. Może mogę trochę pograć w golfa ...

Przykład użycia:

*Main> f                     -- call via f
Questions                    -- User input
Answers                      -- no newline after second line!
uestions                     -- Output starts here
Aestions
Anstions
Ansions
Answons
Answens
Answers

To brutalna siła, która decyduje między zmianą a usunięciem, jeśli początkowe znaki różnią się.

nimi
źródło
Jak długo trwa uruchomienie?
Loovjo,
Jak mogę przetestować (może ideone)?
edc65,
@Loovjo: krótsze ciągi, takie jak twoje przykłady, są obliczane natychmiast, najgorszy przypadek to około 1: 30min. Zinterpretowałem, że „powinien” powinien być uruchamiany w mniej niż minutę ”, a nie jako ścisły limit (powinien vs. Jeśli jest to konieczne, mogę dodać „pakiet wydajności” na około 20 bajtów.
nimi
@ edc65: tak, ideone, ale oczekuje, że funkcja, która ma zostać wykonana, zostanie nazwana „main”. Spróbuj: ideone.com/CUgU8W
nimi