Last active
August 29, 2015 14:07
-
-
Save neilmayhew/9b3e7eeb79b65b79e75e to your computer and use it in GitHub Desktop.
Calculate solutions to the 8 queens on a 5x5 board problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE TupleSections #-} | |
import Control.Arrow (first, second) | |
import Control.Monad (forM_) | |
import Data.List (intersperse, intersect, (\\)) | |
import System.IO (hFlush, stdout) | |
-- Generate the list of possible choices of n items from a list | |
-- Each choice is a pair of the chosen and not-chosen items | |
choices 0 xs = [([], xs)] | |
choices _ [] = [] | |
choices n (x:xs) = map (first (x:)) (choices (n-1) xs) ++ map (second (x:)) (choices n xs) | |
-- The list of positions that can be taken by a queen at position (r, c) | |
sightings (r, c) = | |
[ (y, c) | y <- [0..4], y /= r ] ++ | |
[ (r, x) | x <- [0..4], x /= c ] ++ | |
[ (y, x) | y <- [0..4], y /= r, let x = c-r+y, 0 <= x && x <= 4 ] ++ | |
[ (y, x) | y <- [0..4], y /= r, let x = c+r-y, 0 <= x && x <= 4 ] | |
-- Remove positions that are visible from a white position | |
prune (ws, rest) = (ws, foldl (\\) rest $ map sightings ws) | |
-- Arrange blacks in whatever remains | |
blacken = second (map fst . choices 5) | |
-- Change a first with a list of seconds into a list of first and seconds | |
flatten (x, ys) = map (x,) ys | |
-- Lists of positions and arrangements | |
everywhere = [(r, c) | r <- [0..4], c <- [0..4]] | |
whitings = choices 3 everywhere | |
solutions = concatMap (flatten . blacken . prune) whitings | |
-- Put the given arrangement of pieces on a board | |
arrange (whites, blacks) = [[color (r, c) | c <- [0..4]] | r <- [0..4]] | |
where color p | |
| p `elem` whites = 'W' | |
| p `elem` blacks = 'B' | |
| otherwise = '-' | |
-- Render a board as a multi-line string | |
showBoard = unlines . map (intersperse ' ') | |
-- Output all the solutions | |
main = forM_ solutions $ \s -> do | |
putStrLn . showBoard . arrange $ s | |
hFlush stdout |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment