module Exercise01 where import Test.QuickCheck import Data.List {-H1.1a)-} myPair :: Integer -> Integer -> Integer myPair x y = (2^y) * (2*x + 1) -1 {-H1.1b)-} mySnd :: Integer -> Integer mySnd pair = mySnd' (pair+1) 0 where mySnd' pair y | even pair = mySnd' (div pair 2) (y+1) | otherwise = y {-H1.1c)-} myFst :: Integer -> Integer myFst pair = myFst' (pair+1) where myFst' pair | even pair = myFst' (div pair 2) | otherwise = div (pair - 1) 2 {-H1.1d)-} prop_myPair :: Integer -> Integer -> Integer -> Property prop_myPair p x y = x>=0 && y >= 0 ==> p == myPair x y {-H2-} digitToEo :: Integer -> String digitToEo 0 = "nul" digitToEo 1 = "unu" digitToEo 2 = "du" digitToEo 3 = "tri" digitToEo 4 = "kvar" digitToEo 5 = "kvin" digitToEo 6 = "ses" digitToEo 7 = "sep" digitToEo 8 = "ok" digitToEo 9 = "nau" {-WETT-} --split the number into digits and feed the reverse to listToString, the concatenate the words numberToEo :: Integer -> [Char] numberToEo 0 = "nul" --handle special case numberToEo num = unwords . listToString 0 . reverse $ read . return <$> show num --handle a list of digits three at a time listToString :: Integer -> [Integer] -> [[Char]] listToString _ [] = mempty -- no digits -> no words listToString 1 (1:0:0:xs) = listToString 2 xs ++ pure "mil" -- special case: only write mil instead of unu mil listToString ending (a:b:c:xs) = succ ending `listToString` xs ++ withEndingToString c "cent" ++ withEndingToString b "dek" ++ withEndingToString a "" ++ endingToString ending (a+2* ( b+c)) listToString ending xs = listToString ending $ xs ++ pure 0 -- fill with 0 if no triple left endingToString :: Integer -> Integer -> [[Char]] endingToString 0 _ = mempty -- keine endung bei 1 endingToString _ 0 = mempty -- keine Endung wenn alle 0 endingToString num 1 = pure $ words "ignore mil miliono miliardo duiliono duiliardo triiliono triiliardo kvariliono kvariliardo kviniliono kviniliardo sesiliono sesiliardo sepiliono sepiliardo okiliono okiliardo nauiliono nauiliardo dekiliono dekiliardo" `genericIndex` num endingToString num _ = pure $ words "ignore mil milionoj miliardoj duilionoj duiliardoj triilionoj triiliardoj kvarilionoj kvariliardoj kvinilionoj kviniliardoj sesilionoj sesiliardoj sepilionoj sepiliardoj okilionoj okiliardoj nauilionoj nauiliardoj dekilionoj dekiliardoj"`genericIndex` num withEndingToString :: Integer -> [Char] -> [[Char]] withEndingToString 0 _ = mempty -- digit zero -> no word withEndingToString 1 "" = pure "unu" -- special case 1 in einerstelle withEndingToString 1 ending = pure ending -- specialcase 1 keine zahl, nur endung withEndingToString number ending = pure $ digitToEo number <> ending {-TTEW-} generateEnding num = (if num <= 3 then "m" else numberToEo $ div num 2) ++ if even num then "iliono" else "iliardo" allEndings :: String allEndings = unwords $ map generateEnding [2..21] generateEndingPlural num = generateEnding num ++ "j" allEndingsPlural :: String allEndingsPlural = unwords $ map generateEndingPlural [2..21]