Ogni passo della distanza Levenshtein


18

In questa sfida scriverai un programma che accetta due stringhe separate da nuova riga, s1 (la prima riga) e s2 (la seconda riga), come input (STDIN o più vicino). Puoi presumere che la lunghezza di s1 sarà sempre inferiore a 30 e maggiore della lunghezza di s2. Il programma dovrebbe quindi produrre ogni passaggio della distanza levenshtein da s1 a s2.

Per chiarire cosa significa ogni passaggio nella distanza di levenshtein, il programma stamperà n stringhe, dove n è la distanza di levenshtein tra s1 e s2 e la distanza di levenshtein tra due stringhe adiacenti sarà sempre una. L'ordine non ha importanza. L'output deve essere separato da newline e non includere s1, ma solo gli in-betweens e s2. Il programma dovrebbe anche funzionare in meno di un minuto su un computer moderno.

Esempi:

Ingresso:

Programming
Codegolf

Produzione:

rogramming
Cogramming
Coramming
Coamming
Codmming
Codeming
Codeging
Codegong
Codegolg
Codegolf

Ingresso:

Questions
Answers

Produzione:

uestions
Aestions
Anstions
Ansions
Answons
Answens
Answers

Ingresso:

Offline
Online

Produzione:

Ofline
Online

Ingresso:

Saturday
Sunday

Produzione:

Sturday
Surday
Sunday

Ecco un collegamento a uno script Python che stampa la distanza e i passaggi.

Regole aggiuntive:

Questo è code-golf quindi tieni il codice breve; vince il codice più corto!


1
Per la mia modifica, ho piuttosto supposto che l'input fosse del modulo s1(newline)s2, tuttavia, dopo aver esaminato di nuovo la domanda, mi chiedo se invece intendevi che il programma selezionasse s1 e s2 in base alla lunghezza di 2 stringhe inserite, arrivando in entrambi gli ordini, ti dispiacerebbe chiarire questo punto? Cioè, supponiamo che l'ingresso sia s1 seguito da s2 o selezioniamo s1 e s2 in base alla lunghezza dei due ingressi?
VisualMelon

Una risposta deve essere eseguita in un tempo ragionevole?
KSab

Camper - Ampere, distanza 2, lo script Python funziona per sempre ...
edc65

Quanto è rigoroso "ricevere input da STDIN o dal più vicino"? Posso scrivere una funzione che accetta l'input tramite l'argomento funzione? La risposta attualmente accettata lo fa.
nimi

Risposte:


4

Javascript, 167 161 154 byte

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

Chiama con l("Programming","golf")

Codepen

Codice degradato (e annotato) (obsoleto, ma ottieni l'idea):

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

funzione l (a, b, d) {s = "slice"; 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 il

@nimi: se lo chiami con due argomenti (es. l ("programmazione", "codegolf")) funziona allo stesso modo, quindi suppongo che il tuo punto sia nullo.
9999 anni

Inoltre, dichiarando sdentro a=a[s](1)come si a=a[s="slice"](1)risparmiano alcuni byte.
Mama Fun Roll

1
Secondo il collegamento a codepen, il programma emette 11 passaggi per "Programming"-> "Codegolf", ma dovrebbe essere 10.
nimi

10

Haskell, 201 194 byte

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

Più del previsto. Forse posso giocarci un po '...

Esempio di utilizzo:

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

È una forza bruta che decide tra il cambiamento e l'eliminazione se i caratteri iniziali differiscono.


Quanto ci vuole per correre?
Loovjo,

Come posso testare (forse ideone)?
edc65,

@Loovjo: stringhe più brevi come i tuoi esempi vengono calcolate istantaneamente, il caso peggiore è di circa 1: 30min. Ho interpretato che "should" in "dovrebbe essere eseguito in meno di un minuto" non come un limite rigoroso (dovrebbe vs. must). Se questo è un must, posso aggiungere un "pacchetto prestazioni" per circa 20 byte.
nimi,

@ edc65: sì, ideone, ma si aspetta che la funzione da eseguire venga chiamata "principale". Prova: ideone.com/CUgU8W
Nome del modello
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.