Кожен крок відстані Левенштейна


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, сценарій пітона працює вічно ...
edc65

Наскільки суворо "приймати дані від STDIN або найближчих"? Чи можу я написати функцію, яка приймає вхід через аргумент функції? В даний час прийнята відповідь робить це.
німі

Відповіді:


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; if (a [d]! = b [d]) a = a [s] (0, d) + b [d] + a [s] (d + 1); document.write (a + "<p>" ); l (a, b, ++ d)}}
Доктор Біль

@nimi: Якщо ви називаєте це двома аргументами (наприклад, l ("програмування", "codegolf")), він працює так само, тож я вважаю, що ваш пункт недійсний.
9999років

Крім того , оголошуючи sв a=a[s](1)якості a=a[s="slice"](1)економить кілька байт.
Mama Fun Roll

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
Ними
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.