I noticed this
challenge on RosettaCode, so I decided to try it out and this is the result.
It's actually rather difficult to explain what it does, but here goes:
Give it up to 254 space-delimited lists of words and it will return a completed string in which the last character of one word is the same as the first character of the next.
Here's an example along with the function AMB():
Code:
set1 := "the that a"
set2 := "frog elephant thing"
set3 := "walked treaded grows"
set4 := "slowly quickly"
msgbox % amb( "", set1, set2, set3, set4 )
; this takes a total of 17 iterations to complete
amb( char = "", set1 = "", set2 = "", set3 = "", set4 = "" )
{ ; orginial call to amb must leave char param blank
loop, parse, set1, %a_space%
if (char = (idxchar := substr(a_loopfield, 1, 1)) && set2 = ""
|| (char = idxchar || char = "") && ((retval:= amb(substr(a_loopfield, 0, 1), set2, set3, set4)) != ""))
return a_loopfield " " retval
return ""
}
The variables named "s[num]" are sets of words of which only one will be chosen for that position.
If you want to add more sets of words to compare, just add up to 254 sequentially numbered 's*' params to the definition and also to the call on it's line 3.
To see the number of iterations it took to build your string, uncomment the "errorlevel++" part and put "ErrorLevel = 0" just before you call AMB() and ErrorLevel will contain the number of comparisons done to get this match.
The example returns the string: "tha
t thin
g grow
s slowly"
I colored the letters that it matches different colors so as to explain better.
History:
v0.1: Initial build. Was 8 lines long and took ~108 iterations to complete this example.
v1.0: First release. Reduced to 4 lines and ~58 iterations to complete this example.
v1.1: Current. Rework logic and now takes 17 iterations to complete this example.