60 lines
1.8 KiB
Haskell
60 lines
1.8 KiB
Haskell
module Main where
|
|
|
|
import Data.List (find)
|
|
import Data.Char (toUpper)
|
|
|
|
firstNums :: [String]
|
|
firstNums =
|
|
[ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
|
|
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
|
]
|
|
|
|
tens :: [String]
|
|
tens = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
|
|
|
|
biggerNumbers :: [(Int, String)]
|
|
biggerNumbers =
|
|
[(100, "hundred"), (1000, "thousand"), (1000000, "million"), (1000000000, "billion"), (1000000000000, "trillion")]
|
|
|
|
cardinal :: Int -> String
|
|
cardinal n
|
|
| n' < 20 =
|
|
negText ++ firstNums !! n'
|
|
| n' < 100 =
|
|
negText ++ tens !! (n' `div` 10 - 2) ++ if n' `mod` 10 /= 0 then "-" ++ firstNums !! (n' `mod` 10) else ""
|
|
| otherwise =
|
|
let (num, name) =
|
|
maybe
|
|
(last biggerNumbers)
|
|
fst
|
|
(find (\((num_, _), (num_', _)) -> n' < num_') (zip biggerNumbers (tail biggerNumbers)))
|
|
smallerNum = cardinal (n' `div` num)
|
|
in negText ++ smallerNum ++ " " ++ name ++ if n' `mod` num /= 0 then " " ++ cardinal (n' `mod` num) else ""
|
|
where
|
|
n' = abs n
|
|
negText = if n < 0 then "negative " else ""
|
|
|
|
capitalized :: String -> String
|
|
capitalized (x : xs) = toUpper x : xs
|
|
capitalized [] = []
|
|
|
|
magic :: Int -> String
|
|
magic =
|
|
go True
|
|
where
|
|
go first num =
|
|
let cardiNum = cardinal num
|
|
in (if first then capitalized else id) cardiNum ++ " is "
|
|
++ if num == 4
|
|
then "magic."
|
|
else cardinal (length cardiNum) ++ ", " ++ go False (length cardiNum)
|
|
|
|
main :: IO ()
|
|
main = do
|
|
putStrLn $ magic 3
|
|
putStrLn $ magic 15
|
|
putStrLn $ magic 4
|
|
putStrLn $ magic 10
|
|
putStrLn $ magic 20
|
|
putStrLn $ magic (-13)
|
|
putStrLn $ magic 999999
|