Skip to content

Instantly share code, notes, and snippets.

@twfarland
Created May 13, 2012 16:17
Show Gist options
  • Save twfarland/2689119 to your computer and use it in GitHub Desktop.
Save twfarland/2689119 to your computer and use it in GitHub Desktop.
Search problem solutions using generalised search functions
import SearchPath -- https://gist.github.com/2667320
-- Missionaries and Cannibals
mc = let start = ((3, 3, 1, 0, 0, 0), "")
isGoal (state, _) = state == (0, 0, 0, 3, 3, 1)
action m c = (take m (repeat 'M')) ++ (take c (repeat 'C'))
successors ((m1, c1, b1, m2, c2, b2), _)
| c1 > m1 && m1 > 0 || c2 > m2 && m2 > 0 = []
| b1 > 0 = [((m1 - m, c1 - c, b1 - 1, m2 + m, c2 + c, b2 + 1), (action m c) ++ "->") |
m <- [0 .. m1 + 1],
c <- [0 .. c1 + 1],
m + c > 0, m + c < 3]
| b2 > 0 = [((m1 + m, c1 + c, b1 + 1, m2 - m, c2 - c, b2 - 1), "<-" ++ (action m c)) |
m <- [0 .. m1 + 1],
c <- [0 .. c1 + 1],
m + c > 0, m + c < 3]
| otherwise = []
in shortestPath successors isGoal start
-- Snake Cube Puzzle
snakes = let directions = [[1,0,0], [-1,0,0], [0,1,0], [0,-1,0], [0,0,1], [0,0,-1]]
outOfBounds x = x < 0 || x > 2
getSwivel dir = [dir' |
dir' <- directions,
dir' /= dir,
dir' /= (map negate dir)]
start = ([0,0,0], ([1,0,0], "001110110111010111101010100"))
isGoal (_, (_, blocks)) = length blocks == 1
successors (coord, (dir, (b : blocks)))
| any outOfBounds coord = []
| otherwise = let dirs = case b of
'0' -> [dir]
'1' -> getSwivel dir
in [(coord', (d, blocks)) |
d <- dirs,
let coord' = zipWith (+) coord d]
successors _ = []
in [(pos, dir) | (pos, (dir, _)) <- directedPath successors isGoal start]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment