APL, 109 103 101
Assuming s and k are defined
~⍨/{{∪⊃,/{⍵≡'':⍕¨0 1⋄(,/⍕¨↑(⍎¨⍵)∘≠¨↓∘.=⍨x),(/∘⍵¨↓∘.≠⍨x),(,⍨-0,x)⌽¨,'01'∘.,⌽∘⍵¨0,x←⍳⍴⍵}¨⍵}⍣⍵⊂s}¨0,⍳k
Explantion
The program consists of 3 nested functions.
The inner function {⍵≡'':⍕¨0 1⋄(,/⍕¨↑(⍎¨⍵)∘≠¨↓∘.=⍨x),(/∘⍵¨↓∘.≠⍨x),(,⍨-0,x)⌽¨,'01'∘.,⌽∘⍵¨0,x←⍳⍴⍵}returns all string that is distance 1 from the argument
(,⍨-0,x)⌽¨,'01'∘.,⌽∘⍵¨0,x←⍳⍴⍵ calculate insertions:
⍴⍵ length of the argument
⍳ generate array from 1 to that number
x← assign to variable x
0, concatenate 0 to the start of the array
⌽∘⍵¨ and for each of the number in the array, rotate the argument by that amount, generating an array of strings (rotate is defined as taking characters from the start of the string and appending to the back)
'01'∘., generate a matrix whose first row are the strings with 0 concatenated to the start and the second row are the strings with 1 concatenated to the start
, unravel the matrix to give a simple array of its elements
(,⍨-0,x) give the negatives of the array constructed by concatenating 0 to the start of x, and then concatenate that with another copy of it
⌽¨ finally, rotate the strings back by using the negative numbers
(/∘⍵¨↓∘.≠⍨x) calculates deletions:
∘.≠⍨x generate a square matrix consisting of 0's on the diagonal and 1's elsewhere, whose side is same length as x
↓ split the matrix rows to create a nested array
/∘⍵¨ for each of those arrays, replicate the characters of the argument according the the array (in the case where the array only contains 0's and 1's, it means where there is a 1 in the array, keep the character in the corresponding index and where there is a 0, discard the corresponding character)
(,/⍕¨↑(⍎¨⍵)∘≠¨↓∘.=⍨x) calculates substitutions:
∘.=⍨x generate a square matrix consisting of 1's on the diagonal and 0's elsewhere, whose side is same length as x
↓ split the matrix rows to create a nested array
(⍎¨⍵)∘≠¨ generate an array by converting the argument into a numerical array of its digits, then XOR it with each of the arrays from the split
↑ "mix" the nested array to create a matrix (reverse of split)
⍕¨ for each element of the matrix (which is either 1 or 0), convert to string
,/ for each row of the matrix, concatenate the elements
⍵≡'':⍕¨0 1 is a special case for the empty string (the substitution part will throw an error on empty string)
⍵≡'': if the argument is the empty string...
⍕¨0 1 return this (an array of the strings '0' and '1')
The middle function {∪⊃,/{...}¨⍵} takes an array of strings and return an array of all strings that is distance 1 from any of them
{...}¨⍵ for each of the strings in the argument, use the inner function to get all strings distance 1 for it
,/ concatenate all of the returned arrays
⊃ as the result is "wrapped" in a scalar, "unwrap" it
∪ remove duplicates
The outer function {{...}⍣⍵⊂s}, given a number, calculates all string that is potentially that distance from s
{...}⍣⍵ repeat the middle function ⍵ times (⍵ is the argument)
⊂s "wrap" s and call the function with that as the argument
The remaining part ~⍨/{...}¨0,⍳k
0,⍳k generate array from 0 to k
{...}¨ for each of those numbers, call the outer function with it
~⍨/ remove the strings found in distances 0,1,2,...,k-1 from the strings found in distance k. This is necessary because the "distance 1" function is stateless - it does not consider stuff like substituting the same character twice or inserting and deleting the same character.
3I'd suggest you make the input string variable, too. Also, you might want to specify which forms of I/O are allowed. Full program? Function? ARGV? STDIN? STDOUT? Return value? Oh one more thing, all strings over which alphabet? – Martin Ender – 2014-09-19T17:05:35.100
1And examples are always a good idea. Plus explaining what "edit distance" in your description AND linking to wikipedia is also good. – AndoDaan – 2014-09-19T17:11:39.643
2What constraints are there on the alphabet? Even for
1/0only, there are a large number of outputs for a given string length and distance. It's much worse if you're using [a-z], [A-Za-z], etc. – Geobits – 2014-09-19T17:29:42.893Reminds me of the "Causes Challenge". And Norvig's spell checker. The additional constraint that the found words are in some dictionary might also be interesting; it would mean you can iterate the word list and compute edit distance, or chose to mutate the input string and check each against the dictionary. The no-word-twice seems to be natural to both approaches, though, and not be hard to program around. – Will – 2014-09-19T17:36:34.617
@MartinBüttner Thanks. No input needed. You can just put the string directly into the source. – None – 2014-09-19T17:44:47.557
@Geobits The alphabet is 1 or 0. The output size can be large is k is large and so is the string. – None – 2014-09-19T17:47:22.473
Do we count the length of the code by assuming
kis set to a one-digit number such as1? – Ingo Bürk – 2014-09-19T18:08:08.4101@IngoBürk Usually, if the input can be hardcoded that means you just assume that
kalready has its value, so you don't count the assignment. – Martin Ender – 2014-09-19T18:09:44.427@IngoBürk Yes assume k is a one-digit number. – None – 2014-09-19T18:10:58.500
1Can you give some example results? I get 302 different strings for
k = 2. – Martin Ender – 2014-09-19T18:57:08.747@MartinBüttner Banned. See update. – None – 2014-09-19T19:10:26.443
1
I've added the number of results for different k so people can check there submissions (along with the script used to generate them). I would have added a CW answer but that's not where test data belongs.
– Martin Ender – 2014-09-20T12:45:47.727Can we assume
k≤length(s)? – TwiNight – 2014-09-21T07:29:13.503@TwiNight length(s) = 10 and k is a single digit number.. so ... yes :) – None – 2014-09-21T15:59:24.653
@Lembik I was thinking about cases like s='1010' and k=5 – TwiNight – 2014-09-22T03:43:05.670