Skip to content

Instantly share code, notes, and snippets.

@wchargin
Last active March 25, 2016 15:47
Show Gist options
  • Select an option

  • Save wchargin/c0902a9ad57601b242b8 to your computer and use it in GitHub Desktop.

Select an option

Save wchargin/c0902a9ad57601b242b8 to your computer and use it in GitHub Desktop.
parallel and sequential n-queens in 40 lines
import System.Environment (getArgs)
import Control.Parallel.Strategies (parMap, rpar)
import Control.Monad (mplus, guard)
type Square = (Int, Int)
-- |threat p q|: is |p| queen-threatened by |q|?
threat :: Square -> Square -> Bool
threat (x, y) (x', y') =
x == x' || y == y' || x + y == x' + y' || x - y == x' - y'
-- |conflict p qs|: is |p| queen-threatened by any of the |qs|?
conflict :: Square -> [Square] -> Bool
conflict = any . threat
-- |addQueen i n qs|: |qs| is a list of queens, one per row |1 <= r < i|
addQueen :: Int -> Int -> [Square] -> Maybe [Square]
addQueen i n qs =
let try j
| conflict here qs = retry
| i == n = Just (here : qs)
| otherwise = addQueen (i + 1) n (here : qs) `mplus` retry
where
here = (i, j)
retry = guard (j /= n) >> try (j + 1)
in try 1
-- |queens n|: try to find a set of |n| safe queens on an |n|-by-|n| board
queens :: Int -> Maybe [Square]
queens n = addQueen 1 n []
-- usage: ./Queens {parallel,sequential} <startfrom> +RTS -s -N
main :: IO ()
main = do
(strategy : nStr : _) <- getArgs
let n = read nStr :: Int
let mapper = case strategy of
"sequential" -> map
"parallel" -> parMap rpar
mapM_ print (mapper queens [n..n+7])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment