module Exercise05 where -- May or may not be useful: computes the logarithm base 2 (rounded down) of the given number. -- You don't have to move this into the WETT tags if you want to use it. log2 :: (Integral a, Num b) => a -> b log2 = let go acc n = if n <= 1 then acc else go (acc + 1) (n `div` 2) in go 0 {-WETT-} decompose :: [Integer] -> [Integer] decompose ds | min > 0 = reverse $ decomposeDimension (toInteger (length ds) -1) (map (toReducedBinary $ log2 min) ds) | otherwise = [] where min = minimum ds decomposeDimension :: Integer -> [[Integer]] -> [Integer] decomposeDimension 0 (ds : _) = ds decomposeDimension dim (ds : dss) = zipWith (+) (zipWith (*) (scanl1 (\x y -> 2 * x + y) ds) cs) (zipWith (*) (scanl (\x y -> (2 ^ dim) * (x + y)) 0 cs) ds) where cs = decomposeDimension (dim -1) dss decomposeDimension _ _ = [] toReducedBinary :: Integer -> Integer -> [Integer] toReducedBinary _ 0 = [] toReducedBinary 0 x = [x] toReducedBinary max x = toReducedBinary (max - 1) (x `div` 2) ++ [x `mod` 2] {-TTEW-}