Cada passo da distância de Levenshtein

18

Neste desafio, você escreverá um programa que utiliza duas seqüências separadas por nova linha, s1 (a primeira linha) e s2 (a segunda linha), como entrada (STDIN ou mais próxima). Você pode assumir que o comprimento de s1 sempre será menor que 30 e maior que o comprimento de s2. O programa deve emitir cada passo na distância levenshtein de s1 a s2.

Para esclarecer o significado de cada etapa na distância levenshtein, o programa imprimirá n strings, onde n é a distância levenshtein entre s1 e s2 e a distância levenshtein entre duas strings adjacentes será sempre uma. A ordem não importa. A saída deve ser separada por nova linha e não incluir s1, apenas entre-s e s2. O programa também deve ser executado em menos de um minuto em um computador moderno.

Exemplos:

Entrada:

Programming
Codegolf

Resultado:

rogramming
Cogramming
Coramming
Coamming
Codmming
Codeming
Codeging
Codegong
Codegolg
Codegolf

Entrada:

Questions
Answers

Resultado:

uestions
Aestions
Anstions
Ansions
Answons
Answens
Answers

Entrada:

Offline
Online

Resultado:

Ofline
Online

Entrada:

Saturday
Sunday

Resultado:

Sturday
Surday
Sunday

Aqui está um link para um script python que imprime a distância e as etapas.

Regras adicionais:

Isso é código-golfe, então mantenha seu código curto; o menor código vence!

Loovjo
fonte
1
Para minha edição, presumi que a entrada teria o formato s1(newline)s2, no entanto, tendo examinado a questão novamente, pergunto-me se, em vez disso, você pretendia que o programa selecionasse s1 e s2 com base no comprimento de 2 strings inseridas, chegando em qualquer ordem, você se importaria de esclarecer esse ponto? Ou seja, assumimos que a entrada é s1 seguida por s2 ou selecionamos s1 e s2 com base no comprimento das duas entradas?
VisualMelon
Uma resposta precisa ser executada em um período de tempo razoável?
KSab
Camper - Ampere, distância 2, o script python corre para sempre ...
edc65
Quão rigoroso é "obter informações do STDIN ou mais próximo"? Posso escrever uma função que aceita a entrada via argumento da função? A resposta atualmente aceita faz isso.
N

Respostas:

4

Javascript, 167 161 154 bytes

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

Ligue com l("Programming","golf")

Codepen

Código degolfado (e anotado) (desatualizado, mas você entendeu):

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
  }
}
9999anos
fonte
função l (a, b, d) {s = "fatia"; if (a! = b) {if (a.length> b.length) a = a [s] (1), d = -1; 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: Se você chamá-lo com dois argumentos (por exemplo, l ("programação", "codegolf")), ele funciona da mesma forma, então suponho que seu argumento seja nulo.
9999years 7/03/16
Além disso, declarar sdentro a=a[s](1)como a=a[s="slice"](1)salva alguns bytes.
Mama Fun Roll
1
De acordo com o link para codepen, o programa gera 11 passos para "Programming"-> "Codegolf", mas deve ser 10.
nimi
10

Haskell, 201 194 bytes

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

Mais do que o esperado. Talvez eu possa jogar um pouco ...

Exemplo de uso:

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

É uma força bruta que decide entre alterar e excluir se os caracteres iniciais diferirem.

nimi
fonte
Quanto tempo leva para executar?
Loovjo
Como posso testar (talvez ideona)?
edc65
@Loovjo: seqüências mais curtas como seus exemplos são calculadas instantaneamente, o pior caso é de 1: 30min. Eu interpretei o "deveria" em "deve ser executado em menos de um minuto", não como um limite estrito (deveria vs. deve). Se for necessário, posso adicionar um "pacote de desempenho" por cerca de 20 bytes.
nimi
@ edc65: sim, ideone, mas espera que a função a ser executada seja chamada "main". Tente: ideone.com/CUgU8W
nimi