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!


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

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.