module Prep where import Data.Bifunctor (Bifunctor (bimap)) import Data.Bool (bool) separate :: [Int] -> ([Int], [Int]) separate [] = ([], []) separate [x] = ([x], []) separate (x1 : x2 : xs) = let (next1, next2) = separate xs in (x1 : next1, x2 : next2) -- >>> separate [1..5] -- ([1,3,5],[2,4]) numToStr :: Int -> Int -> String numToStr n radix | n < radix = [chars !! n] | otherwise = numToStr (n `div` radix) radix ++ [chars !! (n `mod` radix)] where chars = "0123456789ABCDEF" -- >>> numToStr 52 10 -- >>> numToStr 5 2 -- >>> numToStr 255 16 -- "52" -- "101" -- "FF" split :: Int -> [a] -> [[a]] split n xs = let prefix = take n xs suffix = drop n xs in if length prefix < n || null suffix then [prefix] else prefix : split n suffix -- >>> split 3 [1..10] -- >>> split 3 [1, 2] -- >>> split 3 [1, 2, 3] -- [[1,2,3],[4,5,6],[7,8,9],[10]] -- [[1,2]] -- [[1,2,3]] averageN :: Int -> [Int] -> [Float] averageN n xs = [fromIntegral s / fromIntegral l | x <- split n xs, let s = sum x, let l = length x] -- >>> averageN 3 [-1, 0, 1, 2, 3] -- [0.0,2.5] -- TASKS (but good luck... :dennis:) copy :: Int -> String -> String copy 0 _ = "" copy n s = s ++ copy (n - 1) s -- >>> copy 3 "abc" -- "abcabcabc" luhnDouble :: Int -> Int luhnDouble = ((> 9) >>= bool id (subtract 9)) . (2 *) -- >>> luhnDouble <$> [0..9] -- [0,2,4,6,8,1,3,5,7,9] luhn :: [Int] -> Bool luhn = (== 0) . (`mod` 10) . uncurry (+) . bimap sum sum . fmap (fmap luhnDouble) . separate . reverse -- >>> luhn [1,7,8,4] -- >>> luhn [4,7,8,3] -- True -- False