Chaque pas de la distance Levenshtein

18

Dans ce défi, vous allez écrire un programme qui prend en entrée deux chaînes séparées par une nouvelle ligne, s1 (la première ligne) et s2 (la deuxième ligne) (STDIN ou la plus proche). Vous pouvez supposer que la longueur de s1 sera toujours inférieure à 30 et supérieure à la longueur de s2. Le programme doit ensuite sortir chaque étape dans la distance de levenshtein de s1 à s2.

Pour clarifier ce que signifie chaque étape de la distance levenshtein, le programme imprimera n chaînes, où n est la distance levenshtein entre s1 et s2, et la distance levenshtein entre deux chaînes adjacentes sera toujours une. L'ordre n'a pas d'importance. La sortie doit être séparée par des sauts de ligne et ne pas inclure s1, uniquement les entre-deux et s2. Le programme devrait également fonctionner en moins d'une minute sur un ordinateur moderne.

Exemples:

Contribution:

Programming
Codegolf

Production:

rogramming
Cogramming
Coramming
Coamming
Codmming
Codeming
Codeging
Codegong
Codegolg
Codegolf

Contribution:

Questions
Answers

Production:

uestions
Aestions
Anstions
Ansions
Answons
Answens
Answers

Contribution:

Offline
Online

Production:

Ofline
Online

Contribution:

Saturday
Sunday

Production:

Sturday
Surday
Sunday

Voici un lien vers un script python qui affiche la distance et les étapes.

Règles supplémentaires:

C'est du code-golf, alors gardez votre code court; le code le plus court gagne!

Loovjo
la source
1
Pour mon montage, j'ai plutôt présumé que l'entrée serait de la forme s1(newline)s2, cependant, après avoir relu la question, je me demande si vous aviez plutôt l'intention que le programme sélectionne s1 et s2 en fonction de la longueur de 2 chaînes entrées, venant dans l'un ou l'autre ordre, pourriez-vous clarifier ce point? Autrement dit, supposons-nous que l'entrée est s1 suivie de s2, ou sélectionnons-nous s1 et s2 en fonction de la longueur des deux entrées?
VisualMelon
Une réponse doit-elle être exécutée dans un délai raisonnable?
KSab
Camper - Ampère, distance 2, le script python tourne pour toujours ...
edc65
Quelle est la rigueur de "prendre la contribution de STDIN ou le plus proche"? Puis-je écrire une fonction qui prend l'entrée via un argument de fonction? La réponse actuellement acceptée le fait.
nimi

Réponses:

4

Javascript, 167 161 154 octets

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)}}

Appeler avec l("Programming","golf")

Codepen

Code dégolfé (et annoté) (obsolète mais vous avez l'idée):

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
  }
}
9999ans
la source
fonction l (a, b, d) {s = "tranche"; if (a! = b) {if (a.length> b.length) 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: Si vous l'appelez avec deux arguments (par exemple l ("programmation", "codegolf")) cela fonctionne de la même façon, donc je suppose que votre point est nul.
9999ans
De plus, déclarer sinside a=a[s](1)comme a=a[s="slice"](1)économise quelques octets.
Mama Fun Roll
1
Selon le lien vers codepen, votre programme affiche 11 étapes pour "Programming"-> "Codegolf", mais cela devrait être 10.
nimi
10

Haskell, 201 194 octets

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

Plus long que prévu. Peut-être que je peux jouer au golf un peu ...

Exemple d'utilisation:

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

C'est une force brute qui décide entre changer et supprimer si les caractères initiaux diffèrent.

nimi
la source
Combien de temps faut-il pour courir?
Loovjo
Comment puis-je tester (peut-être idéone)?
edc65
@Loovjo: les chaînes plus courtes comme vos exemples sont calculées instantanément, le pire des cas est d'environ 1h30. J'ai interprété le «devrait» dans «devrait fonctionner en moins d'une minute» et non comme une limite stricte (devrait contre doit). Si c'est un must, je peux ajouter un "pack performance" pour environ 20 octets.
nimi
@ edc65: oui, ideone, mais il s'attend à ce que la fonction à exécuter soit appelée "main". Essayez: ideone.com/CUgU8W
nimi