module S03 (
ptriples,
prefixes,
suffixes,
sublists,
smartStack,
smartTile,
) where
import Picture
import Data.List
ptriples n = [(x,y,z) | x <- [1..n], y <- [x..n], z <- [y+1..n], x^2 + y^2 == z^2]
prefixes :: [a] -> [[a]]
prefixes [] = [[]]
prefixes (x:xs) = [] : map (x:) (prefixes xs)
suffixes :: [a] -> [[a]]
suffixes [] = [[]]
suffixes (x:xs) = (x:xs) : suffixes xs
sublistsBySize :: [a] -> [[[a]]]
sublistsBySize [] = [[[]]]
sublistsBySize (x:xs) = zipWith (++) ([] : map (map (x:)) xss) (xss ++ [[]])
where
xss = sublistsBySize xs
sublists :: [a] -> [[a]]
sublists = concat . sublistsBySize
center :: Int -> Picture -> Picture
center n (h, w, css)
| w <= n = (h, n, map centerline css)
| otherwise = error ("picture of width " ++ show w ++
" does not fit in box of width " ++ show n)
where
centerline l = left ++ l ++ right
left = replicate (nc + nh wh wc) ' '
right = replicate (nh wh) ' '
nc = if n `mod` 2 == 0 then 0 else 1
wc = if w `mod` 2 == 0 then 0 else 1
wh = w `div` 2
nh = n `div` 2
centerv :: Int -> Picture -> Picture
centerv n (h, w, css)
| h <= n = (n, w, top ++ css ++ bot)
| otherwise = error ("picture of height " ++ show h ++
" does not fit in box of height " ++ show n)
where
top = replicate (nc + nh hh hc) (replicate w ' ')
bot = replicate (nh hh) (replicate w ' ')
nc = if n `mod` 2 == 0 then 0 else 1
hc = if h `mod` 2 == 0 then 0 else 1
hh = h `div` 2
nh = n `div` 2
smartAbove :: Picture -> Picture -> Picture
smartAbove p q = center w p `above` center w q
where
w = max (width p) (width q)
smartBeside :: Picture -> Picture -> Picture
smartBeside p q = centerv h p `beside` centerv h q
where
h = max (height p) (height q)
smartStack, smartSpread :: [Picture] -> Picture
smartStack = foldl1 smartAbove
smartSpread = foldl1 smartBeside
smartTile :: [[Picture]] -> Picture
smartTile = smartStack . map smartSpread