Difference between revisions of "Haskell Quiz/English Numerals/Solution Michael Sloan"

From HaskellWiki
Jump to navigation Jump to search
m
 
(2 intermediate revisions by one other user not shown)
Line 1: Line 1:
[[Category:Code]]
+
[[Category:Haskell Quiz solutions|English Numerals]]
   
 
Probably not as elegant as it could be, but handles a huge number of... numbers. More than any of the ruby programs, I'm sure. Feel free to edit it for elegance.
 
Probably not as elegant as it could be, but handles a huge number of... numbers. More than any of the ruby programs, I'm sure. Feel free to edit it for elegance.
Line 21: Line 21:
 
ename n = (if n < 20 then ["m", "b", "tr", "quadr", "quint", "sext","sept", "oct", "non"] !! ((n `div` 2)-1)
 
ename n = (if n < 20 then ["m", "b", "tr", "quadr", "quint", "sext","sept", "oct", "non"] !! ((n `div` 2)-1)
 
else (prefixes !! ((n `div` 2) `mod` 10)) ++ (suffixes !! (n `div` 20 - 1))
 
else (prefixes !! ((n `div` 2) `mod` 10)) ++ (suffixes !! (n `div` 20 - 1))
) ++ "illi" ++ (if n `mod` 2 == 0 then "on" else "ard")
+
) ++ "illi" ++ (if even n then "on" else "ard")
   
 
digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
 
digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]

Latest revision as of 20:47, 14 December 2009


Probably not as elegant as it could be, but handles a huge number of... numbers. More than any of the ruby programs, I'm sure. Feel free to edit it for elegance.

prefixes =                ["", "un", "duo","tre","quattuor","quin",   "sex", "septen","octo", "novem"]
suffixes = ["dec"]++(map (++"gint") ["vi", "tri","quadra",  "quinqua","sexa","septua","octo", "nona"])

aname 0 = ""
aname 1 = "thousand"
aname 101 = "centillion"
aname n | n > 101 = error "Can't name american numbers over with more than 303 decimal digits"
aname n = (if n <= 10 then    ["m",  "b",  "tr", "quadr",   "quint",  "sext","sept",  "oct",  "non"] !! (n-2)
                     else (prefixes !! ((n-1) `mod` 10)) ++ (suffixes !! ((n-1) `div` 10 - 1))
         ) ++ "illion"

ename 0 = ""
ename 1 = "thousand"
ename 200 = "centillion"
ename 201 = "centilliard"
ename n | n > 201 = error "Can't name european numbers over with more than 603 decimal digits"
ename n = (if n < 20 then    ["m",  "b",  "tr", "quadr",   "quint",  "sext","sept",  "oct",  "non"] !! ((n `div` 2)-1)
                     else (prefixes !! ((n `div` 2) `mod` 10)) ++ (suffixes !! (n `div` 20 - 1))
         ) ++ "illi" ++ (if even n then "on" else "ard")

digits = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]

triple :: Integer -> Int -> (Int -> String) -> String
triple 0 _ _ = ""
triple n i f | n > 999 = triple (n `div` 1000) (i+1) f ++ (if n `mod` 1000 /= 0 then ", " ++ triple (n `mod` 1000) i f else "")
triple n 0 _ | n > 99 && (n `mod` 100) == 0 = digits !! (fromIntegral $ n `div` 100) ++ " hundred"
triple n 0 f | n > 99 = triple (n `div` 100 * 100) 0 f ++ " and " ++ triple (n `mod` 100) 0 f
triple n 0 _ | n `mod` 10 == 0 = ["", "ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"] !! (fromIntegral $ n `div` 10)
triple n 0 _ | n > 10 && n < 20 = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"] !! (fromIntegral $ n - 11)
triple n 0 _ | n < 10 = digits !! (fromIntegral n)
triple n 0 f = triple (n `div` 10 * 10) 0 f ++ " " ++ triple (n `mod` 10) 0 f
triple n i f | n <= 999 = triple n 0 f ++ " " ++ f i

americanNumber 0 = "zero"
americanNumber x = triple x 0 aname

europeanNumber 0 = "zero"
europeanNumber x = triple x 0 ename