Monday, February 21, 2011

magic squares

If your magic square needs are more industrial there are always better ways...
import Data.List (transpose, intersect)
 
answers  =  filter valid squares
              where valid m = diag1 m == 15 && diag2 m == 15
 
squares  =  horz combos `intersect` vert combos
              where vert = map transpose . horz
 
combos   =  [ [a,b,c] | a <- ns, b <- ns, c <- ns, a + b + c == 15 ]
              where ns = [1..9]
 
horz m   =  [ [a,b,c] | a <- m, b <- m, c <- m, uniq (a ++ b ++ c) ]
 
diag1 m  =  head (head m) + ((m !! 1) !! 1) + last (last m)
  
diag2 m  =  last (head m) + ((m !! 1) !! 1) + head (last m)
 
uniq ns  =  let f (n:ns) xs = n `notElem` xs && f ns (n:xs)
                f _ _       = True
            in f ns []