Skip to content

Instantly share code, notes, and snippets.

@jbpotonnier
Created October 26, 2012 23:28
Show Gist options
  • Save jbpotonnier/3962166 to your computer and use it in GitHub Desktop.
Save jbpotonnier/3962166 to your computer and use it in GitHub Desktop.
Solving http://www.rubyquiz.com/quiz60.html with the power of list monad
import Control.Monad (guard)
double :: Int -> Int
double = (2 *)
add_two :: Int -> Int
add_two = (2 +)
halve :: Int -> Int
halve n = n `div` 2
paths :: Int -> Int -> [[Int]]
paths start target = map reverse $ search [start]
where
search :: [Int] -> [[Int]]
search path@(x:xs) = do
guard $ length path < 10
op <- if even x then [double, add_two, halve] else [double, add_two]
let new = op x
guard $ new `notElem` path
if new == target
then return $ new:path
else search $ new:path
@jbpotonnier
Copy link
Author

Example :

*Main> paths 9 2
[[9,18,20,22,24,12,6,8,4,2],[9,18,20,10,12,14,16,8,4,2],[9,18,20,10,12,6,8,4,2],[9,11,22,24,12,14,16,8,4,2],[9,11,22,24,12,6,8,4,2],[9,11,13,26,28,14,16,8,4,2],[9,11,13,15,30,32,16,8,4,2]]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment