Каждый шаг расстояния Левенштейна


18

В этом задании вы напишите программу, которая принимает две строки, разделенные символом новой строки, s1 (первая строка) и s2 (вторая строка), в качестве входных данных (STDIN или ближайший). Вы можете предположить, что длина s1 всегда будет меньше 30 и больше, чем длина s2. Затем программа должна выводить каждый шаг на расстоянии Левенштейна от s1 до s2.

Чтобы уточнить, что означает каждый шаг расстояния Левенштейна, программа напечатает n строк, где n - расстояние Левенштейна между s1 и s2, а расстояние Левенштейна между двумя соседними строками всегда будет равно единице. Порядок не имеет значения. Выходные данные должны быть разделены новой строкой и не включать s1, только промежуточные и s2. Программа также должна работать менее чем за одну минуту на современном компьютере.

Примеры:

Входные данные:

Programming
Codegolf

Выход:

rogramming
Cogramming
Coramming
Coamming
Codmming
Codeming
Codeging
Codegong
Codegolg
Codegolf

Входные данные:

Questions
Answers

Выход:

uestions
Aestions
Anstions
Ansions
Answons
Answens
Answers

Входные данные:

Offline
Online

Выход:

Ofline
Online

Входные данные:

Saturday
Sunday

Выход:

Sturday
Surday
Sunday

Вот ссылка на скрипт Python, который распечатывает расстояние и шаги.

Дополнительные правила:

Это код-гольф, поэтому держите код коротким; самый короткий код выигрывает!


1
Что касается моего редактирования, я скорее предположил, что ввод будет иметь форму s1(newline)s2, однако, еще раз просмотрев вопрос, мне интересно, если бы вместо этого вы хотели, чтобы программа выбрала s1 и s2 на основе длины 2 введенных строк, приходя в любом порядке, не могли бы вы уточнить этот момент? То есть мы предполагаем, что на входе s1 следует s2, или мы выбираем s1 и s2 на основе длины двух входов?
VisualMelon

Должен ли ответ проходить в разумные сроки?
KSab

Кемпер - Ампер, дистанция 2, скрипт на
питоне

Насколько строгим является «принять вход от STDIN или ближайший»? Могу ли я написать функцию, которая принимает входные данные через аргумент функции? В настоящее время принятый ответ делает так.
Nimi

Ответы:


4

Javascript, 167 161 154 байта

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

Позвонить с l("Programming","golf")

Codepen

Дегольфед (и аннотированный) код (устарел, но вы поняли):

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

функция l (a, b, d) {s = "срез"; if (a! = b) {if (a.length> b.length) a = a [s] (1), d = -1; еще если (! а [d] = б [г]) а = [s] (0, D) + B [D] + а [с] (D + 1); document.write (а + "<P>" ); l (a, b, ++ d)}}
доктор Пейн

@nimi: Если вы называете это с двумя аргументами (например, l («program», «codegolf»)), это работает одинаково, поэтому я полагаю, что ваша точка равна нулю.
9999лет

Кроме того, объявление sвнутри, так a=a[s](1)как a=a[s="slice"](1)сохраняет некоторые байты.
Мама Ролл

1
По ссылке на codepen ваша программа выводит 11 шагов для "Programming"-> "Codegolf", но это должно быть 10.
nimi

10

Haskell, 201 194 байта

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

Дольше, чем ожидалось. Может быть, я могу немного поиграть в гольф ...

Пример использования:

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

Это грубая сила, которая решает между изменением и удалением, если начальные символы различаются.


Как долго длится бег?
Loovjo

Как я могу проверить (возможно, ideone)?
edc65

@Loovjo: более короткие строки, такие как ваши примеры, рассчитываются мгновенно, наихудший случай составляет около 1: 30мин. Я интерпретировал, что "должен" в "должен выполняться менее чем за одну минуту", а не как строгий предел (должен против должен). Если это необходимо, я могу добавить «пакет производительности» для около 20 байтов.
Ними

@ edc65: да, ideone, но он ожидает, что выполняемая функция будет называться "основной". Попробуйте: ideone.com/CUgU8W
nimi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.