レーベンシュタイン距離の各ステップ


18

この課題では、2つの改行で区切られた文字列s1(最初の行)とs2(2番目の行)を入力(STDINまたは最も近い)として受け取るプログラムを作成します。s1の長さは常に30より小さく、s2の長さより大きいと仮定できます。プログラムは、s1からs2までのレーベンシュタイン距離の各ステップを出力します。

レーベンシュタイン距離の各ステップの意味を明確にするために、プログラムはn個のストリングを出力します。ここで、nはs1とs2の間のレーベンシュタイン距離であり、2つの隣接するストリング間のレーベンシュタイン距離は常に1です。順序は関係ありません。出力は改行で区切る必要があり、s1は含めず、中間とs2のみを含める必要があります。このプログラムは、最新のコンピューターで1分以内に実行されるはずです。

例:

入力:

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が、もう一度質問を見て、2つの入力文字列の長さに基づいてプログラムがs1とs2を選択することを意図していたのではないかと思っていますどちらの順序でも、この点を明確にしていただけますか?つまり、入力はs1の後にs2が続くと仮定しますか、または2つの入力の長さに基づいてs1とs2を選択しますか?
VisualMelon

回答は妥当な時間内に実行する必要がありますか?
KSab

キャンピングカー-アンペア、距離2、pythonスクリプトは永遠に実行されます
...-edc65

「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")

コードペン

Degolfed(および注釈付き)コード(時代遅れですが、あなたはアイデアを得る):

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 = "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)}}
ペイン博士

@nimi:2つの引数(l( "programming"、 "codegolf")など)で呼び出すと同じように動作するため、ポイントはnullであると考えられます。
9999

また、sinside a=a[s](1)として宣言すると、a=a[s="slice"](1)いくつかのバイトが節約されます。
ママファンロール

1
codepenへのリンクによると、プログラムは"Programming"-> に対して11ステップを出力します"Codegolf"が、10になるはずです。
nimi16年

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

どうすればテストできますか(イデオンかもしれません)?
edc65

@Loovjo:例のような短い文字列は即座に計算され、最悪の場合は約1:30分です。私は、「1分以内に実行する必要がある」という「すべき」を、厳密な制限として解釈すべきではありません(必須と必須)。これが必要な場合は、約20バイトの「パフォーマンスパック」を追加できます。
nimi

@ edc65:はい、ideoneですが、実行される関数が「メイン」と呼ばれることを期待しています。試してみてください:ideone.com/CUgU8W
nimi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.