Number names: Difference between revisions

From Rosetta Code
Content added Content deleted
(added J)
(Added Haskell.)
Line 44: Line 44:
forty-three million, one hundred and twelve thousand, six hundred and nine
forty-three million, one hundred and twelve thousand, six hundred and nine


=={{header|Haskell}}==
<pre>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"]</pre>


== {{header|J}} ==
== {{header|J}} ==

Revision as of 18:13, 10 October 2008

Task
Number names
You are encouraged to solve this task according to the task description, using any language you may know.

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

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"]

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