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

From HaskellWiki

Line 1: | Line 1: | ||

⚫ | |||

+ | [[Category:Code]] |
||

+ | |||

⚫ | |||

<haskell>prefixes = ["", "un", "duo","tre","quattuor","quin", "sex", "septen","octo", "novem"] |
<haskell>prefixes = ["", "un", "duo","tre","quattuor","quin", "sex", "septen","octo", "novem"] |

## Revision as of 01:29, 10 November 2006

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 n `mod` 2 == 0 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
```