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 :: StartList -> ResultList decompose :: [Integer] -> [Integer] decompose ds = reverse $ dropWhile (==0) $ decomposeHelper ds ((toInteger . length) ds) ((log2 . minimum) ds) -- decomposeHelper :: PartOfList -> lengthOfList -> minLog -> ResultList decomposeHelper :: [Integer] -> Integer -> Integer -> [Integer] decomposeHelper _ 0 _ = replicate 100 0 decomposeHelper [d] 1 m = binaryList d m decomposeHelper (d:ds) l m = decomposeIterator (decomposeHelper ds (l-1) m) d (l-1) -- decomposeIterator :: depth:PartOfList -> currentDepth -> dimension -> ResultList decomposeIterator :: [Integer] -> Integer -> Integer -> [Integer] decomposeIterator [] _ i = [] decomposeIterator (d:ds) c i = backwardsOuterZip (map (*d) (binaryListSplitWrapper c ((toInteger . length) ds) i)) (decomposeIterator ds c i) -- binaryList :: depth -> minLog -> ResultList -- similar to binaryListSplit, but I didn't want to use 5 parameters for binaryListSplit... binaryList :: Integer -> Integer -> [Integer] binaryList _ (-1) = [] binaryList d m = sum : binaryList (d - sum * pow) (m-1) where pow = 2^m sum = d `div` pow -- binaryListSplitWrapper :: currentDepth -> minLog -> dimension -> ResultList binaryListSplitWrapper :: Integer -> Integer -> Integer -> [Integer] binaryListSplitWrapper d m = binaryListSplit d m m -- binaryListSplit :: currentDepth -> minLog -> startLog -> dimension -> ResultList binaryListSplit :: Integer -> Integer -> Integer -> Integer -> [Integer] binaryListSplit _ (-1) _ _ = [] binaryListSplit d m s i = sum * (2^((s - m) * i)) : binaryListSplit (d - sum * pow) (m-1) s i where pow = 2^m sum = d `div` pow -- backwardsOuterZip :: ListA -> ListB -> ResultList backwardsOuterZip :: [Integer] -> [Integer] -> [Integer] backwardsOuterZip xs ys = reverse $ outerZip (reverse xs) (reverse ys) -- outerZip :: ListA -> ListB -> ResultList outerZip :: [Integer] -> [Integer] -> [Integer] outerZip [] xs = xs outerZip ys [] = ys outerZip (x:xs) (y:ys) = (x + y) : outerZip xs ys {-TTEW-}