Skip to content

Instantly share code, notes, and snippets.

@chris-taylor
Last active January 2, 2016 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chris-taylor/8348612 to your computer and use it in GitHub Desktop.
Save chris-taylor/8348612 to your computer and use it in GitHub Desktop.
Given two words *from* and *to*, transform *from* into *to* by either adding, removing or altering one letter at a time, so that each step in the transformation is a valid English word.
import Control.Applicative
import qualified Data.Set as Set
import AI.Search.Uninformed
step :: Set.Set String -> String -> [] String
step wordlist xs = Set.toList . Set.fromList . filter f $ remove1 xs ++ swap1 xs ++ add1 xs
where
f w = Set.member w wordlist
len = length xs
letters = ['a'..'z']
remove1 xs = [take n xs ++ drop (n+1) xs | n <- [0..len-1]]
add1 xs = [take n xs ++ [x] ++ drop n xs | x <- letters, n <- [0..len]]
swap1 xs = [take n xs ++ [x] ++ drop (n+1) xs | x <- letters, n <- [0..len-1]]
makeWordProblem :: Set.Set String -> String -> String -> SearchProblem String ()
makeWordProblem wl from to = SearchProblem
{ probInitialState = from
, probSuccessor = \w -> map (\w -> ((),w)) (step wl w)
, probGoalTest = (== to)
, probCost = \s a s' -> 1
}
solve :: String -> String -> IO String
solve from to = do
wordlist <- Set.fromList . lines <$> readFile "3esl.txt"
case breadthFirstGraphSearch (makeWordProblem wordlist from to) of
Nothing -> putStrLn "NO SOLUTION FOUND"
Just node -> mapM_ (putStrLn . nodeState) (reverse $ path node)
{------------------------
>> :load wordgame.hs
>> solve "black" "white"
black
back
balk
bale
hale
whale
while
white
>> solve "milk" "pail"
milk
mill
mall
mail
pail
>>
-------------------------}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment