Magic squares of doubly even order: Difference between revisions

Content added Content deleted
m (→‎{{header|Haskell}}: (Slightly simpler diagonals function – dropped a lambda))
Line 570: Line 570:
magicSquare :: Int -> [[Int]]
magicSquare :: Int -> [[Int]]
magicSquare n
magicSquare n
| rem n 4 > 0 = []
| rem n 4 > 0 = []
| otherwise = splitEvery n $
| otherwise =
splitEvery n $
-- Taken directly from the integer series where True
-- and from the reverse of that series where False
-- Taken directly from the integer series where True
-- and from the reverse of that series where False
zipWith (\x i -> if x then i else limit - i)
series
zipWith
[1..sqr]
(\x i ->
if x
then i
else limit - i)
series
[1 .. sqr]
where
sqr = n * n
limit = sqr + 1
series
-- For integer powers of 2, the (append not) 'magic' series directly
-- yields the truth table that we need
| isPowerOf 2 n = magicSeries $ floor (logBase 2 (fromIntegral sqr))
-- where n is not an integer power of 2, we can replicate a
-- minimum truth table, horizontally and vertically
| otherwise =
concat . concat . concat . scale $
scale <$> splitEvery 4 (magicSeries 4)
where
where
sqr = n * n
scale = replicate $ quot n 4
limit = sqr + 1
series
-- For integer powers of 2, the (append not) 'magic' series directly
-- yields the truth table that we need
| isPowerOf 2 n =
magicSeries $ floor (logBase 2 (fromIntegral sqr))

-- where n is not an integer power of 2, we can replicate a
-- minimum truth table, horizontally and vertically
| otherwise = concat . concat . concat .
scale $ scale <$> splitEvery 4 (magicSeries 4)
where
scale = replicate $ quot n 4



------------------------------------------------------------------------
------------------------------------------------------------------------

magicSeries :: Int -> [Bool]
magicSeries :: Int -> [Bool]
magicSeries = (iterate (\xs -> xs ++ (not <$> xs)) [True] !!)
magicSeries = (iterate (\xs -> xs ++ (not <$> xs)) [True] !!)
Line 603: Line 605:


isPowerOf :: Int -> Int -> Bool
isPowerOf :: Int -> Int -> Bool
isPowerOf k n =
isPowerOf k n = until (\x -> rem x k /= 0) (`quot` k) n == 1
until (\x -> rem x k /= 0)
(`quot` k) n == 1


main :: IO ()
main :: IO ()
main = mapM_ print $ magicSquare 8
main = mapM_ print $ magicSquare 8


----------------------------------------------------------------------
-- Summed and checked---------------------------------------------------

-- Summed and checked
checked :: Int -> (Int, Bool)
checked :: Int -> (Int, Bool)
checked n = (h, all (h ==) t)
checked n = (h, all (h ==) t)
where
where
square = magicSquare n
square = magicSquare n
h:t = sum <$> square ++ -- rows
h:t =
sum <$>
transpose square ++ -- cols
diagonals square -- diagonals
square ++ -- rows
transpose square ++ -- cols
diagonals square -- diagonals


diagonals :: [[Int]] -> [[Int]]
diagonals :: [[Int]] -> [[Int]]
diagonals xs =
diagonals xs = flip (zipWith (!!)) [0 ..] <$> [xs, reverse xs]
flip (zipWith (!!)) [0..] <$> [xs, reverse xs]


main2 :: IO ()
main2 :: IO ()