module Exercise05 where main = decompose [123] -- 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 |not (null [n| n <- ds, n == 0 ]) = [] |length ds == 1 && head ds < 2 = ds |length ds == 1 = let anzahlStell = log2 (minimum ds) in addElements [div n anzahlStell |n <- [0..anzahlStell] ] (decompose [head ds - 2 ^ anzahlStell]) |otherwise = helpFunk [decompose [n]| n <- ds] 1 helpFunk:: [[Integer]] -> Integer -> [Integer] helpFunk [] _ = [] helpFunk (xs:xss) iter |null xss = xs |otherwise = let (first, second) = ifDifferent (xs, head xss) iter in helpFunk ([n | x <- [0..(length first-1)], n <- [sum ([first!!x * (second!!parts) * (2 ^ (parts - x))| parts <- [x..length second-1]] ++ [second!!x * (first!!parts) * (2 ^ ((parts - x ) * fromInteger iter)) | parts <-[x+1..length first - 1]]) ] ] : tail xss) (iter+1) ifDifferent::([Integer], [Integer]) -> Integer -> ([Integer], [Integer]) ifDifferent paar iter | length (fst paar) == length (snd paar) = paar | length (fst paar) > length (snd paar) = ifDifferent (init(init (fst paar)) ++ [last (fst paar) * (2 ^ iter) + last(init (fst paar))], snd paar) iter | otherwise = ifDifferent (fst paar, init(init (snd paar)) ++ [last (snd paar) * 2 + last(init (snd paar))]) iter addElements:: [Integer] -> [Integer] -> [Integer] addElements f s = addElementsHelp f s [] addElementsHelp:: [Integer] -> [Integer] -> [Integer]-> [Integer] addElementsHelp [] secondList result = result ++ secondList; addElementsHelp firstList [] result = result ++ firstList addElementsHelp firstList secondList result = addElementsHelp (tail firstList) (tail secondList) (result ++ [head firstList + head secondList]) {-TTEW-}