Skip to content

Instantly share code, notes, and snippets.

@IanCal
Created February 18, 2012 10:16
Show Gist options
  • Save IanCal/1858601 to your computer and use it in GitHub Desktop.
Save IanCal/1858601 to your computer and use it in GitHub Desktop.
A closed form solution for n-queens, from "Explicit Solutions to the N-Queens Problem for all N"
type Queen = (Int,Int)
solveNot6kplus2 :: Int -> [Queen]
solveNot6kplus2 n = firstHalf ++ secondHalf
where
firstHalf = [(j, 2 * j) | j <- range]
secondHalf = [(n `div` 2 + j, 2 * j - 1) | j <- range]
range = [1 .. n `div` 2]
solveNot6k :: Int -> [Queen]
solveNot6k n = firstHalf ++ secondHalf
where
firstHalf = [(n+1 - j, n - getY j) | j <- range]
secondHalf = [(j, 1 + getY j) | j <- range]
getY j = mod (2 * (j-1) + n `div` 2 - 1) n
range = [1 .. n `div` 2]
solve n
| mod n 2 /= 0 = (n,n) : solve (n-1)
| mod n 6 /= 0 = solveNot6k n
| mod (n - 2) 6 /= 0 = solveNot6kplus2 n
isValid :: [Queen] -> Bool
isValid stack = foldl validate True pairs
where pairs = [(s1,s2) | s1 <- stack, s2 <- stack, s1 /= s2]
validate False _ = False
validate True ((x1,y1), (x2,y2)) =
x1 /= x2 && y1 /= y2 && (abs $ y2 - y1) /= (abs $ x2 - x1)
check = all isValid [solve n | n <- [4..1000]]
main = print $ length $ solve 1000000
--main = print check
{--
> ghc --make -O3 -fforce-recomp nqueens.hs; time ./nqueens
[1 of 1] Compiling Main ( nqueens.hs, nqueens.o )
Linking nqueens ...
1000000
real 0m0.074s
user 0m0.064s
sys 0m0.008s
--}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment