Convert an integer into words
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.
Contents |
[edit] Ada
with Ada.Text_IO; use Ada.Text_IO; procedure Integers_In_English is type Spellable is range 0..999_999_999_999_999_999; function Spell (N : Spellable) return String is function Twenty (N : Spellable) return String is begin case N mod 20 is when 0 => return "zero"; when 1 => return "one"; when 2 => return "two"; when 3 => return "three"; when 4 => return "four"; when 5 => return "five"; when 6 => return "six"; when 7 => return "seven"; when 8 => return "eight"; when 9 => return "nine"; when 10 => return "ten"; when 11 => return "eleven"; when 12 => return "twelve"; when 13 => return "thirteen"; when 14 => return "fourteen"; when 15 => return "fifteen"; when 16 => return "sixteen"; when 17 => return "seventeen"; when 18 => return "eighteen"; when others => return "nineteen"; end case; end Twenty; function Decade (N : Spellable) return String is begin case N mod 10 is when 2 => return "twenty"; when 3 => return "thirty"; when 4 => return "forty"; when 5 => return "fifty"; when 6 => return "sixty"; when 7 => return "seventy"; when 8 => return "eighty"; when others => return "ninety"; end case; end Decade; function Hundred (N : Spellable) return String is begin if N < 20 then return Twenty (N); elsif 0 = N mod 10 then return Decade (N / 10 mod 10); else return Decade (N / 10) & '-' & Twenty (N mod 10); end if; end Hundred; function Thousand (N : Spellable) return String is begin if N < 100 then return Hundred (N); elsif 0 = N mod 100 then return Twenty (N / 100) & " hundred"; else return Twenty (N / 100) & " hundred and " & Hundred (N mod 100); end if; end Thousand; function Triplet ( N : Spellable; Order : Spellable; Name : String; Rest : not null access function (N : Spellable) return String ) return String is High : Spellable := N / Order; Low : Spellable := N mod Order; begin if High = 0 then return Rest (Low); elsif Low = 0 then return Thousand (High) & ' ' & Name; else return Thousand (High) & ' ' & Name & ", " & Rest (Low); end if; end Triplet; function Million (N : Spellable) return String is begin return Triplet (N, 10**3, "thousand", Thousand'Access); end Million; function Milliard (N : Spellable) return String is begin return Triplet (N, 10**6, "million", Million'Access); end Milliard; function Billion (N : Spellable) return String is begin return Triplet (N, 10**9, "milliard", Milliard'Access); end Billion; function Billiard (N : Spellable) return String is begin return Triplet (N, 10**12, "billion", Billion'Access); end Billiard; begin return Triplet (N, 10**15, "billiard", Billiard'Access); end Spell; begin Put_Line (" 99 " & Spell ( 99)); Put_Line (" 300 " & Spell ( 300)); Put_Line (" 310 " & Spell ( 310)); Put_Line (" 1_501 " & Spell ( 1_501)); Put_Line (" 12_609 " & Spell ( 12_609)); Put_Line (" 512_609 " & Spell ( 512_609)); Put_Line (" 43_112_609 " & Spell ( 43_112_609)); Put_Line (" 77_000_112_609 " & Spell ( 77_000_112_609)); Put_Line ("2_000_000_000_100 " & Spell (2_000_000_000_100)); end Integers_In_English;
The solution is recursive by the triplets of decimal numbers. The implementation goes up to 1018-1. Sample output:
99 ninety-nine
300 three hundred
310 three hundred and ten
1_501 one thousand, five hundred and one
12_609 twelve thousand, six hundred and nine
512_609 five hundred and twelve thousand, six hundred and nine
43_112_609 forty-three million, one hundred and twelve thousand, six hundred and nine
77_000_112_609 seventy-seven milliard, one hundred and twelve thousand, six hundred and nine
2_000_000_000_100 two billion, one hundred
[edit] ALGOL 68
PROC number words = (INT n)STRING:(
# returns a string representation of n in words. Currently
deals with anything from 0 to 999 999 999. #
[]STRING digits = []STRING
("zero","one","two","three","four","five","six","seven","eight","nine")[@0];
[]STRING teens = []STRING
("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen")[@0];
[]STRING decades = []STRING
("twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety")[@2];
PROC three digits = (INT n)STRING: (
# does the conversion for n from 0 to 999. #
INT tens = n MOD 100 OVER 10;
INT units = n MOD 10;
(n >= 100|digits[n OVER 100] + " " + "hundred" + (n MOD 100 /= 0|" and "|"")|"") +
(tens /= 0|(tens = 1|teens[units]|decades[tens] + (units /= 0|"-"|""))) +
(units /= 0 AND tens /= 1 OR n = 0|digits[units]|"")
);
INT m = n OVER 1 000 000;
INT k = n MOD 1 000 000 OVER 1000;
INT u = n MOD 1000;
(m /= 0|three digits(m) + " million"|"") +
(m /= 0 AND (k /= 0 OR u >= 100)|", "|"") +
(k /= 0|three digits(k) + " thousand"|"") +
((m /= 0 OR k /= 0) AND u > 0 AND u < 100|" and " |: k /= 0 AND u /= 0|", "|"") +
(u /= 0 OR n = 0|three digits(u)|"")
);
on logical file end(stand in, (REF FILE f)BOOL: stop iteration);
on value error(stand in, (REF FILE f)BOOL: stop iteration);
DO # until user hits EOF #
INT n;
print("n? ");
read((n, new line));
print((number words(n), new line))
OD;
stop iteration:
SKIP
Example input with output:
n? 43112609 forty-three million, one hundred and twelve thousand, six hundred and nine
[edit] Haskell
spellInteger :: Integer -> String
spellInteger n
| n < 0 = error "spellInteger: negative input"
| n < 20 = small n
| n < 100 = let (a, b) = n `divMod` 10
in tens a ++ nonzero '-' b
| n < 1000 = let (a, b) = n `divMod` 100
in small a ++ " hundred" ++ nonzero ' ' b
| otherwise = join $ map big $ reverse $ filter ((/= 0) . snd) $
zip [0..] $ unfoldr uff n
where nonzero :: Char -> Integer -> String
nonzero _ 0 = ""
nonzero c n = c : spellInteger n
join :: [String] -> String
join [s] = s
join (s : ss) = s ++ ", " ++ join ss
uff :: Integer -> Maybe (Integer, Integer)
uff 0 = Nothing
uff n = let (a, b) = n `divMod` 1000
in Just (b, a)
small, tens :: Integer -> String
small = (["zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen"] !!) . fromEnum
tens = ([undefined, undefined, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"] !!) .
fromEnum
big :: (Int, Integer) -> String
big (0, n) = spellInteger n
big (1, n) = spellInteger n ++ " thousand"
big (e, n) = spellInteger n ++ ' ' : (l !! e) ++ "illion"
where l = [undefined, undefined, "m", "b", "tr", "quadr",
"quint", "sext", "sept", "oct", "non", "dec"]
[edit] J
u=. ;:'one two three four five six seven eight nine'
v=. ;:'ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'
t=. ;:'twenty thirty forty fifty sixty seventy eighty ninety'
EN100=: '' ; u , v , , t ,&.>/ '';'-',&.>u
z=. '' ; 'thousand' ; (;:'m b tr quadr quint sext sept oct non'),&.> <'illion'
u=. ;:'un duo tre quattuor quin sex septen octo novem'
t=. (;:'dec vigint trigint quadragint quinquagint sexagint septuagint octogint nonagint'),&.><'illion'
ENU=: z , (, t ,~&.>/ '';u) , <'centillion'
en3=: 4 : 0
'p q'=. 0 100#:y
(p{::EN100),((*p)#' hundred'),((p*&*q)#x),q{::EN100
)
en=: 4 : 0
d=. 1000&#.^:_1 y
assert. (0<:y) *. ((=<.)y) *. d <:&# ENU
c=. x&en3&.> (*d)#d
((0=y)#'zero') , (-2+*{:d) }. ; , c,.(<' '),.(ENU{~I.&.|.*d),.<', '
)
uk=: ' and '&en NB. British
us=: ' ' &en NB. American
Example:
uk 123456789 one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine us 123456789 one hundred twenty-three million, four hundred fifty-six thousand, seven hundred eighty-nine
Categories: Programming Tasks | Arithmetic operations | Ada | ALGOL 68 | Haskell | J

