Number names: Difference between revisions

m
→‎[[Number names#ALGOL 68]]: add an alternative version in a python style...
m (→‎[[Number names#ALGOL 68]]: fix a missing CASE OUT, add GOTO to make compatable with official ALGOL 68 subset.)
m (→‎[[Number names#ALGOL 68]]: add an alternative version in a python style...)
Line 181:
SKIP</lang>
Example input with output:
<lang algol68pre>n? 43112609
forty-three million, one hundred and twelve thousand, six hundred and nine</lang>
</pre>
{{trans|Python}}
 
{{works with|ALGOL 68|Standard - no extensions to language used - note size of LONG LONG INT is implementation specific}}
 
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
<lang Algol68>MODE EXCEPTION = STRUCT(STRING name, PROC VOID handler);
EXCEPTION value error = ("Value Error", stop);
 
PROC raise = (EXCEPTION exception, STRING str error)VOID: (
put(stand error, (name OF exception,": ",str error, new line));
handler OF exception
);
 
MODE LINT = LONG LONG INT;
 
BOOL locale euro := TRUE;
 
PROC spell integer = (LINT n)STRING: (
[]STRING tens = []STRING (~, ~, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety")[@0];
[]STRING small = []STRING ("zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen")[@0];
[]STRING bl = []STRING (~, ~, "m", "b", "tr", "quadr",
"quint", "sext", "sept", "oct", "non", "dec")[@0];
PROC nonzero = (STRING c, LINT n)STRING:
IF n = 0 THEN "" ELSE c + spell integer(n) FI;
PROC big =(INT e, LINT n)STRING:
spell integer(n) +
CASE e+1 IN
#0# "",
#1# " thousand"
OUT
" " +
IF locale euro THEN # handle millard, billard & trillard etc #
bl[e OVER 2 + 1 ]+"ill" + CASE e MOD 2 IN "ard" OUT "ion" ESAC
ELSE
bl[e]+"illion"
FI
ESAC;
PROC base1000 rev = (LINT in n, PROC (INT,LINT)VOID yield)VOID: (
# generates the value of the digits of n in base 1000 #
# (i.e. 3-digit chunks), in reverse. #
LINT n := in n;
FOR e FROM 0 WHILE n /= 0 DO
LINT r = n MOD 1000;
n := n OVER 1000;
yield(e, r)
OD
);
IF n < 1000 THEN
INT ssn := SHORTEN SHORTEN n;
IF ssn < 0 THEN
raise (value error, "spell integer: negative input"); ~
ELIF ssn < 20 THEN
small[ssn]
ELIF ssn < 100 THEN
INT a = ssn OVER 10,
b = ssn MOD 10;
tens[a] + nonzero("-", b)
ELIF ssn < 1000 THEN
INT a = ssn OVER 100,
b = ssn MOD 100;
small[a] + " hundred" + ( b NE 0 | " and" | "") + nonzero(" ", b)
FI
ELSE
STRING out := "", sep:="";
# FOR x IN # base1000 rev(n, # DO #
(INT e, LINT x)VOID:
IF x NE 0 THEN
big(e,x) + sep +=: out;
sep := IF e = 0 AND x < 100 THEN " and " ELSE ", " FI
FI
);
# OD; #
out
FI
);
 
PROC example = (LINT n)VOID:
print((whole(n,0),": ", spell integer(n), new line));
 
# examples #
LINT prod := 0;
FOR i TO 6 DO prod := prod * 10**i + i; example(prod) OD;
 
example(1278); example(1572); example(2010)</lang>Test output:
<pre>
1: one
102: one hundred and two
102003: one hundred and two thousand and three
1020030004: one millard, twenty million, thirty thousand and four
102003000400005: one hundred and two billion, three millard, four hundred thousand and five
102003000400005000006: one hundred and two trillion, three billard, four hundred millard, five million and six
1278: one thousand, two hundred and seventy-eight
1572: one thousand, five hundred and seventy-two
2010: two thousand and ten
</pre>
=={{header|BASIC}}==
{{works with|QBasic}}
Line 1,040 ⟶ 1,145:
 
# example
print spell_integer(1278)</lang>
print spell_integer(1752)
 
print spell_integer(2010)
</lang>
<pre>
one thousand, two hundred seventy-eight
one thousand, seven hundred fifty-two
two thousand, ten
</pre>
=={{header|Ruby}}==
{{trans|Python}}