module Exercise01 where import Test.QuickCheck {-H1.1a)-} myPair :: Integer -> Integer -> Integer myPair x y = ((2 ^ y) * (2 * x + 1)) -1 {-H1.1b)-} mySnd :: Integer -> Integer mySnd p = mySndRec (p + 1) 0 mySndRec p x | even p = mySndRec (p `div` 2) x + 1 | odd p = x {-H1.1c)-} myFst :: Integer -> Integer myFst p = myFstRec (p + 1) myFstRec p | even p = myFstRec (p `div` 2) | odd p = (p - 1) `div` 2 {-H1.1d)-} prop_myPair :: Integer -> Integer -> Integer -> Property prop_myPair p x y = x >= 0 && y >= 0 && p >= 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-} numberToEo :: Integer -> String numberToEo 0 = "nul" numberToEo n = unwords $ numberToEoList n numberToEoList :: Integer -> [String] numberToEoList 0 = [] numberToEoList n | n < 10 = [digitToEo n] | n < 100 = convertSmall n 10 "dek" | n < 1000 = convertSmall n 100 "cent" | otherwise = convertLarge n convertSmall :: Integer -> Integer -> String -> [String] convertSmall n cutoff s = ((if mult > 1 then digitToEo mult else "") ++ s) : numberToEoList rem where (mult, rem) = n `divMod` cutoff convertLarge :: Integer -> [String] convertLarge n = (if power > 1 || mult > 1 then numberToEoList mult else []) ++ [s] ++ numberToEoList rem where power = logThousand n 0 (mult, rem) = n `divMod` (1000 ^ power) s = thousandString power mult logThousand :: Integer -> Integer -> Integer logThousand 0 c = pred c logThousand n c = logThousand (n `div` 1000) $ succ c expandedDigitTo :: Integer -> String expandedDigitTo 1 = "m" expandedDigitTo 10 = "dek" expandedDigitTo power = digitToEo power thousandString :: Integer -> Integer -> String thousandString 1 _ = "mil" thousandString power 1 = expandedDigitTo (power `div` 2) ++ if even power then "iliono" else "iliardo" thousandString power _ = thousandString power 1 ++ "j" {-TTEW-}