tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1 @@
Show how to spell out a number in English. You can use a preexisting implementation or roll your own, but you should support inputs up to at least one million (or the maximum value of your language's default bounded integer type, if that's less). Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.

View file

@ -0,0 +1,2 @@
---
note: Arithmetic operations

View file

@ -0,0 +1,38 @@
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: GOTO stop iteration);
on value error(stand in, (REF FILE f)BOOL: GOTO 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

View file

@ -0,0 +1,89 @@
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 e, 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)

View file

@ -0,0 +1,50 @@
# syntax: GAWK -f NUMBER_NAMES.AWK
BEGIN {
init_numtowords()
n = split("-10 0 .1 8 100 123 1001 99999 100000 9123456789 111000000111",arr," ")
for (i=1; i<=n; i++) {
printf("%s = %s\n",arr[i],numtowords(arr[i]))
}
exit(0)
}
# source: The AWK Programming Language, page 75
function numtowords(n, minus,str) {
if (n < 0) {
n = n * -1
minus = "minus "
}
if (n == 0) {
str = "zero"
}
else {
str = intowords(n)
}
gsub(/ /," ",str)
return(minus str)
}
function intowords(n) {
n = int(n)
if (n >= 1000000000000) {
return intowords(n/1000000000000) " trillion " intowords(n%1000000000000)
}
if (n >= 1000000000) {
return intowords(n/1000000000) " billion " intowords(n%1000000000)
}
if (n >= 1000000) {
return intowords(n/1000000) " million " intowords(n%1000000)
}
if (n >= 1000) {
return intowords(n/1000) " thousand " intowords(n%1000)
}
if (n >= 100) {
return intowords(n/100) " hundred " intowords(n%100)
}
if (n >= 20) {
return tens[int(n/10)] " " intowords(n%10)
}
return(nums[n])
}
function init_numtowords() {
split("one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen",nums," ")
split("ten twenty thirty forty fifty sixty seventy eighty ninety",tens," ")
}

View file

@ -0,0 +1,132 @@
with Ada.Text_IO;
procedure Integers_In_English is
type Spellable is range -999_999_999_999_999_999..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
if N < 0 then
return "negative " & Spell(-N);
else
return Triplet (N, 10**15, "billiard", Billiard'Access);
end if;
end Spell;
procedure Spell_And_Print(N: Spellable) is
Number: constant String := Spellable'Image(N);
Spaces: constant String(1 .. 20) := (others => ' '); -- 20 * ' '
begin
Ada.Text_IO.Put_Line(Spaces(Spaces'First .. Spaces'Last-Number'Length)
& Number & ' ' & Spell(N));
end Spell_And_Print;
Samples: constant array (Natural range <>) of Spellable
:= (99, 300, 310, 1_501, 12_609, 512_609, 43_112_609, 77_000_112_609,
2_000_000_000_100, 999_999_999_999_999_999,
0, -99, -1501, -77_000_112_609, -123_456_789_987_654_321);
begin
for I in Samples'Range loop
Spell_And_Print(Samples(I));
end loop;
end Integers_In_English;

View file

@ -0,0 +1,40 @@
Loop { ; TEST LOOP
n =
Random Digits, 1, 36 ; random number with up to 36 digits
Loop %Digits% {
Random Digit, 0, 9 ; can have leading 0s
n .= Digit
}
MsgBox 1, Number Names, % PrettyNumber(n) "`n`n" Spell(n) "`n`n"
IfMsgBox Cancel, Break
}
Spell(n) { ; recursive function to spell out the name of a max 36 digit integer, after leading 0s removed
Static p1=" thousand ",p2=" million ",p3=" billion ",p4=" trillion ",p5=" quadrillion ",p6=" quintillion "
, p7=" sextillion ",p8=" septillion ",p9=" octillion ",p10=" nonillion ",p11=" decillion "
, t2="twenty",t3="thirty",t4="forty",t5="fifty",t6="sixty",t7="seventy",t8="eighty",t9="ninety"
, o0="zero",o1="one",o2="two",o3="three",o4="four",o5="five",o6="six",o7="seven",o8="eight"
, o9="nine",o10="ten",o11="eleven",o12="twelve",o13="thirteen",o14="fourteen",o15="fifteen"
, o16="sixteen",o17="seventeen",o18="eighteen",o19="nineteen"
n :=RegExReplace(n,"^0+(\d)","$1") ; remove leading 0s from n
If (11 < d := (StrLen(n)-1)//3) ; #of digit groups of 3
Return "Number too big"
If (d) ; more than 3 digits
Return Spell(SubStr(n,1,-3*d)) p%d% ((s:=SubStr(n,1-3*d)) ? ", " Spell(s) : "")
i := SubStr(n,1,1)
If (n > 99) ; 3 digits
Return o%i% " hundred" ((s:=SubStr(n,2)) ? " and " Spell(s) : "")
If (n > 19) ; n = 20..99
Return t%i% ((o:=SubStr(n,2)) ? "-" o%o% : "")
Return o%n% ; n = 0..19
}
PrettyNumber(n) { ; inserts thousands separators into a number string
Return RegExReplace( RegExReplace(n,"^0+(\d)","$1"), "\G\d+?(?=(\d{3})+(?:\D|$))", "$0,")
}

View file

@ -0,0 +1,73 @@
DECLARE FUNCTION int2Text$ (number AS LONG)
'small
DATA "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"
DATA "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
'tens
DATA "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
'big
DATA "thousand", "million", "billion"
DIM SHARED small(1 TO 19) AS STRING, tens(7) AS STRING, big(2) AS STRING
DIM tmpInt AS INTEGER
FOR tmpInt = 1 TO 19
READ small(tmpInt)
NEXT
FOR tmpInt = 0 TO 7
READ tens(tmpInt)
NEXT
FOR tmpInt = 0 TO 2
READ big(tmpInt)
NEXT
DIM n AS LONG
INPUT "Gimme a number! ", n
PRINT int2Text$(n)
FUNCTION int2Text$ (number AS LONG)
DIM num AS LONG, outP AS STRING, unit AS INTEGER
DIM tmpLng1 AS LONG
IF 0 = number THEN
int2Text$ = "zero"
EXIT FUNCTION
END IF
num = ABS(number)
DO
tmpLng1 = num MOD 100
SELECT CASE tmpLng1
CASE 1 TO 19
outP = small(tmpLng1) + " " + outP
CASE 20 TO 99
SELECT CASE tmpLng1 MOD 10
CASE 0
outP = tens((tmpLng1 \ 10) - 2) + " " + outP
CASE ELSE
outP = tens((tmpLng1 \ 10) - 2) + "-" + small(tmpLng1 MOD 10) + " " + outP
END SELECT
END SELECT
tmpLng1 = (num MOD 1000) \ 100
IF tmpLng1 THEN
outP = small(tmpLng1) + " hundred " + outP
END IF
num = num \ 1000
IF num < 1 THEN EXIT DO
tmpLng1 = num MOD 1000
IF tmpLng1 THEN outP = big(unit) + " " + outP
unit = unit + 1
LOOP
IF number < 0 THEN outP = "negative " + outP
int2Text$ = RTRIM$(outP)
END FUNCTION

View file

@ -0,0 +1,40 @@
DIM test%(20)
test%() = 0, 1, 2, 19, 20, 21, 99, 100, 101, 300, 310, 1001, -1327, 1501, \
\ 10203, 12609, 101104, 102003, 467889, 1005006, -123000789
FOR i% = 0 TO DIM(test%(),1)
PRINT FNsaynumber(test%(i%))
NEXT
END
DEF FNsaynumber(n%)
LOCAL number%(), number$(), i%, t%, a$
DIM number%(29), number$(29)
number%() = 1000000000, 1000000, 1000, 100, 90, 80, 70, 60, 50, 40, 30, 20, \
\ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2
number$() = "billion", "million", "thousand", "hundred", "ninety", "eighty", \
\ "seventy", "sixty", "fifty", "forty", "thirty", "twenty", \
\ "nineteen", "eighteen", "seventeen", "sixteen", "fifteen", \
\ "fourteen", "thirteen", "twelve", "eleven", "ten", "nine", \
\ "eight", "seven", "six", "five", "four", "three", "two"
IF n% < 0 THEN = "minus " + FNsaynumber(-n%)
IF n% = 0 THEN = "zero"
IF n% = 1 THEN = "one "
FOR i% = 0 TO DIM(number%(),1)
IF n% >= number%(i%) THEN
t% = n% DIV number%(i%)
IF t%=1 AND i%<4 a$ += "one " ELSE IF t%<>1 a$ += FNsaynumber(t%)
a$ += number$(i%)
t% = n% MOD number%(i%)
CASE TRUE OF
WHEN i%>3 AND i%<12 AND t%<>0: a$ += "-"
WHEN i%<=3 AND t%>=100: a$ += ", "
WHEN i%<=3 AND t%<>0 AND t%<100: a$ += " and "
OTHERWISE: a$ += " "
ENDCASE
IF t% a$ += FNsaynumber(t%) ELSE IF i%<12 a$ += " "
EXIT FOR
ENDIF
NEXT i%
= a$

View file

@ -0,0 +1,69 @@
#include <string>
#include <iostream>
using std::string;
const char* smallNumbers[] = {
"zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"
};
string spellHundreds(unsigned n) {
string res;
if (n > 99) {
res = smallNumbers[n/100];
res += " hundred";
n %= 100;
if (n) res += " and ";
}
if (n >= 20) {
static const char* Decades[] = {
"", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"
};
res += Decades[n/10];
n %= 10;
if (n) res += "-";
}
if (n < 20 && n > 0)
res += smallNumbers[n];
return res;
}
const char* thousandPowers[] = {
" billion", " million", " thousand", "" };
typedef unsigned long Spellable;
string spell(Spellable n) {
if (n < 20) return smallNumbers[n];
string res;
const char** pScaleName = thousandPowers;
Spellable scaleFactor = 1000000000; // 1 billion
while (scaleFactor > 0) {
if (n >= scaleFactor) {
Spellable h = n / scaleFactor;
res += spellHundreds(h) + *pScaleName;
n %= scaleFactor;
if (n) res += ", ";
}
scaleFactor /= 1000;
++pScaleName;
}
return res;
}
int main() {
#define SPELL_IT(x) std::cout << #x " " << spell(x) << std::endl;
SPELL_IT( 99);
SPELL_IT( 300);
SPELL_IT( 310);
SPELL_IT( 1501);
SPELL_IT( 12609);
SPELL_IT( 512609);
SPELL_IT(43112609);
SPELL_IT(1234567890);
return 0;
}

View file

@ -0,0 +1,137 @@
#include <stdio.h>
#include <string.h>
const char *ones[] = { 0, "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
const char *tens[] = { 0, "ten", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety" };
const char *llions[] = { 0, "thousand", "million", "billion", "trillion",
// "quadrillion", "quintillion", "sextillion", "septillion",
// "octillion", "nonillion", "decillion"
};
const int maxillion = sizeof(llions) / sizeof(llions[0]) * 3 - 3;
int say_hundred(const char *s, int len, int depth, int has_lead)
{
int c[3], i;
for (i = -3; i < 0; i++) {
if (len + i >= 0) c[i + 3] = s[len + i] - '0';
else c[i + 3] = 0;
}
if (!(c[0] + c[1] + c[2])) return 0;
if (c[0]) {
printf("%s hundred", ones[c[0]]);
has_lead = 1;
}
if (has_lead && (c[1] || c[2]))
printf((!depth || c[0]) && (!c[0] || !c[1]) ? "and " :
c[0] ? " " : "");
if (c[1] < 2) {
if (c[1] || c[2]) printf("%s", ones[c[1] * 10 + c[2]]);
} else {
if (c[1]) {
printf("%s", tens[c[1]]);
if (c[2]) putchar('-');
}
if (c[2]) printf("%s", ones[c[2]]);
}
return 1;
}
int say_maxillion(const char *s, int len, int depth, int has_lead)
{
int n = len / 3, r = len % 3;
if (!r) {
n--;
r = 3;
}
const char *e = s + r;
do {
if (say_hundred(s, r, n, has_lead) && n) {
has_lead = 1;
printf(" %s", llions[n]);
if (!depth) printf(", ");
else printf(" ");
}
s = e; e += 3;
} while (r = 3, n--);
return 1;
}
void say_number(const char *s)
{
int len, i, got_sign = 0;
while (*s == ' ') s++;
if (*s < '0' || *s > '9') {
if (*s == '-') got_sign = -1;
else if (*s == '+') got_sign = 1;
else goto nan;
s++;
} else
got_sign = 1;
while (*s == '0') {
s++;
if (*s == '\0') {
printf("zero\n");
return;
}
}
len = strlen(s);
if (!len) goto nan;
for (i = 0; i < len; i++) {
if (s[i] < '0' || s[i] > '9') {
printf("(not a number)");
return;
}
}
if (got_sign == -1) printf("minus ");
int n = len / maxillion;
int r = len % maxillion;
if (!r) {
r = maxillion;
n--;
}
const char *end = s + len - n * maxillion;
int has_lead = 0;
do {
if ((has_lead = say_maxillion(s, r, n, has_lead))) {
for (i = 0; i < n; i++)
printf(" %s", llions[maxillion / 3]);
if (n) printf(", ");
}
n--;
r = maxillion;
s = end;
end += r;
} while (n >= 0);
printf("\n");
return;
nan: printf("not a number\n");
return;
}
int main()
{
say_number("-42");
say_number("1984");
say_number("10000");
say_number("1024");
say_number("1001001001001");
say_number("123456789012345678901234567890123456789012345678900000001");
return 0;
}

View file

@ -0,0 +1,2 @@
(clojure.pprint/cl-format nil "~R" 1234)
=> "one thousand, two hundred thirty-four"

View file

@ -0,0 +1,57 @@
spell_integer = (n) ->
tens = [null, null, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"]
small = ["zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"]
bl = [null, null, "m", "b", "tr", "quadr",
"quint", "sext", "sept", "oct", "non", "dec"]
divmod = (n, d) ->
[Math.floor(n / d), n % d]
nonzero = (c, n) ->
if n == 0
""
else
c + spell_integer n
big = (e, n) ->
if e == 0
spell_integer n
else if e == 1
spell_integer(n) + " thousand"
else
spell_integer(n) + " " + bl[e] + "illion"
base1000_rev = (n) ->
# generates the value of the digits of n in base 1000
# (i.e. 3-digit chunks), in reverse.
chunks = []
while n != 0
[n, r] = divmod n, 1000
chunks.push r
chunks
if n < 0
throw Error "spell_integer: negative input"
else if n < 20
small[n]
else if n < 100
[a, b] = divmod n, 10
tens[a] + nonzero("-", b)
else if n < 1000
[a, b] = divmod n, 100
small[a] + " hundred" + nonzero(" ", b)
else
chunks = (big(exp, x) for x, exp in base1000_rev(n) when x)
chunks.reverse().join ', '
# example
console.log spell_integer 1278
console.log spell_integer 1752
console.log spell_integer 2010
console.log spell_integer 4000123007913

View file

@ -0,0 +1,5 @@
> coffee spell_number.coffee
one thousand, two hundred seventy-eight
one thousand, seven hundred fifty-two
two thousand, ten
four trillion, one hundred twenty-three million, seven thousand, nine hundred thirteen

View file

@ -0,0 +1,2 @@
(format nil "~R" 1234)
=> "one thousand two hundred thirty-four"

View file

@ -0,0 +1,60 @@
import std.stdio, std.string;
string spellInteger(in long n) pure nothrow {
static immutable tens = ["", "", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"];
static immutable small = "zero one two three four five six
seven eight nine ten eleven twelve thirteen fourteen
fifteen sixteen seventeen eighteen nineteen".split();
static immutable bl = ["", "", "m", "b", "tr",
"quadr", "quint", "sext", "sept", "oct", "non", "dec"];
static string nonZero(in string c, in int n) pure nothrow {
return n == 0 ? "" : c ~ spellInteger(n);
}
static string big(in int e, in int n) pure nothrow {
switch (e) {
case 0: return spellInteger(n);
case 1: return spellInteger(n) ~ " thousand";
default: return spellInteger(n) ~ " " ~ bl[e] ~ "illion";
}
}
/// Generates the value of the digits of n in
/// base 1000 (i.e. 3-digit chunks), in reverse.
static int[] base1000Reverse(in long nn) pure nothrow {
long n = nn;
int[] result;
while (n) {
result ~= n % 1000;
n /= 1000;
}
return result;
}
if (n < 0) {
return "negative " ~ spellInteger(-n);
} else if (n < 1000) {
int ni = cast(int)n; // D doesn't infer this.
if (ni < 20) {
return small[ni];
} else if (ni < 100) {
return tens[ni / 10] ~ nonZero("-", ni % 10);
} else // ni < 1000
return small[ni / 100] ~ " hundred" ~
nonZero(" ", ni % 100);
} else {
string[] pieces;
foreach_reverse (e, x; base1000Reverse(n))
pieces ~= big(e, x);
return pieces.join(", ");
}
}
void main() {
foreach (i; -10 .. 1_000)
writeln(i, " ", spellInteger(i));
}

View file

@ -0,0 +1,72 @@
function abs(atom i)
if i < 0 then
return -i
else
return i
end if
end function
constant small = {"one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "ten","eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen",
"seventeen", "eighteen", "nineteen"}
constant tens = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty",
"ninety"}
constant big = {"thousand", "million", "billion"}
function int2text(atom number)
atom num
integer unit, tmpLng1
sequence outP
outP = ""
num = 0
unit = 1
tmpLng1 = 0
if number = 0 then
return "zero"
end if
num = abs(number)
while 1 do
tmpLng1 = remainder(num,100)
if tmpLng1 > 0 and tmpLng1 < 20 then
outP = small[tmpLng1] & ' ' & outP
elsif tmpLng1 >= 20 then
if remainder(tmpLng1,10) = 0 then
outP = tens[floor(tmpLng1/10)-1] & ' ' & outP
else
outP = tens[floor(tmpLng1/10)-1] & '-' & small[remainder(tmpLng1, 10)] & ' ' & outP
end if
end if
tmpLng1 = floor(remainder(num, 1000) / 100)
if tmpLng1 then
outP = small[tmpLng1] & " hundred " & outP
end if
num = floor(num/1000)
if num < 1 then
exit
end if
tmpLng1 = remainder(num,1000)
if tmpLng1 then
outP = big[unit] & ' ' & outP
end if
unit = unit + 1
end while
if number < 0 then
outP = "negative " & outP
end if
return outP[1..$-1]
end function
puts(1,int2text(900000001) & "\n")
puts(1,int2text(1234567890) & "\n")
puts(1,int2text(-987654321) & "\n")
puts(1,int2text(0) & "\n")

View file

@ -0,0 +1,67 @@
program spell
implicit none
integer :: e
integer :: i
integer :: m
integer :: n
character (9), dimension (19), parameter :: small = &
& (/'one ', 'two ', 'three ', 'four ', &
& 'five ', 'six ', 'seven ', 'eight ', &
& 'nine ', 'ten ', 'eleven ', 'twelve ', &
& 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', &
& 'seventeen', 'eighteen ', 'nineteen '/)
character (7), dimension (2 : 9), parameter :: tens = &
& (/'twenty ', 'thirty ', 'forty ', 'fifty ', 'sixty ', &
& 'seventy', 'eighty ', 'ninety '/)
character (8), dimension (3), parameter :: big = &
& (/'thousand', 'million ', 'billion '/)
character (256) :: r
do
read (*, *, iostat = i) n
if (i /= 0) then
exit
end if
if (n == 0) then
r = 'zero'
else
r = ''
m = abs (n)
e = 0
do
if (m == 0) then
exit
end if
if (modulo (m, 1000) > 0) then
if (e > 0) then
r = trim (big (e)) // ' ' // r
end if
if (modulo (m, 100) > 0) then
if (modulo (m, 100) < 20) then
r = trim (small (modulo (m, 100))) // ' ' // r
else
if (modulo (m, 10) > 0) then
r = trim (small (modulo (m, 10))) // ' ' // r
r = trim (tens (modulo (m, 100) / 10)) // '-' // r
else
r = trim (tens (modulo (m, 100) / 10)) // ' ' // r
end if
end if
end if
if (modulo (m, 1000) / 100 > 0) then
r = 'hundred' // ' ' // r
r = trim (small (modulo (m, 1000) / 100)) // ' ' // r
end if
end if
m = m / 1000
e = e + 1
end do
if (n < 0) then
r = 'negative' // ' ' // r
end if
end if
write (*, '(a)') trim (r)
end do
end program spell

View file

@ -0,0 +1,54 @@
package main
import "fmt"
func main() {
for _, n := range []int64{12, 1048576, 9e18} {
fmt.Println(say(n))
}
}
var small = []string{"", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
var tens = []string{"ones", "ten", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"}
var illions = []string{"thousand", "million", "billion",
"trillion", "quadrillion", "quintillion"}
func say(n int64) string {
switch {
case n < 1:
case n < 20:
return small[n]
case n < 100:
t := tens[n/10]
s := n % 10
if s > 0 {
t += " " + small[s]
}
return t
case n < 1000:
h := small[n/100] + " hundred"
s := n % 100
if s > 0 {
h += " " + say(s)
}
return h
default:
sx := say(n % 1000)
for i := 0; n >= 1000; i++ {
n /= 1000
p := n % 1000
if p > 0 {
ix := say(p) + " " + illions[i]
if sx > "" {
ix += " " + sx
}
sx = ix
}
}
return sx
}
return ""
}

View file

@ -0,0 +1,75 @@
def divMod(BigInteger number, BigInteger divisor) {
def qr = number.divideAndRemainder(divisor)
[div:qr[0], remainder:qr[1]]
}
def toText(value) {
value = value as BigInteger
def units = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen']
def tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety']
def big = ['', 'thousand'] + ['m', 'b', 'tr', 'quadr', 'quint', 'sext', 'sept', 'oct', 'non', 'dec'].collect { "${it}illion"}
if (value < 0) {
"negative ${toText(-value)}"
} else if (value < 20) {
units[value]
} else if (value < 100) {
divMod(value, 10).with { "${tens[div]} ${units[remainder]}".replace(' zero', '') }
} else if (value < 1000) {
divMod(value, 100).with { "${toText(div)} hundred and ${toText(remainder)}".replace(' and zero', '') }
} else {
def chunks = []
while (value != 0) {
divMod(value, 1000).with {
chunks << remainder
value = div
}
}
if (chunks.size() > big.size()) {
throw new IllegalArgumentException("Number overflow")
}
def text = []
(0..<chunks.size()).each { index ->
if (chunks[index] > 0) {
text << "${toText(chunks[index])}${index == 0 ? '' : ' ' + big[index]}"
if (index == 0 && chunks[index] < 100) {
text << "and"
}
}
}
text.reverse().join(', ').replace(', and,', ' and')
}
}
// Add this method to all Numbers
Number.metaClass.toText = { toText(delegate) }
println toText(29)
println 40.toText()
println toText(401)
println 9003.toText()
println toText(8011673)
println 8000100.toText()
println 4629436.toText()
948623487512387455323784623842314234.toText().split(',').each { println it.trim() }
def verifyToText(expected, value) {
println "Checking '$expected' == $value"
def actual = value.toText()
assert expected == actual
}
verifyToText 'nineteen', 19
verifyToText 'one thousand, two hundred and thirty four', 1234
verifyToText 'twenty three million, four hundred and fifty nine thousand, six hundred and twelve', 23459612
verifyToText 'one thousand, nine hundred and ninety nine', 1999
verifyToText 'negative six hundred and one', -601
verifyToText 'twelve billion and nineteen', 12000000019
verifyToText 'negative one billion, two hundred and thirty four million, five hundred and sixty seven thousand, eight hundred and ninety', -1234567890
verifyToText 'one hundred and one', 101
verifyToText 'one thousand and one', 1001
verifyToText 'one million, one hundred and one', 1000101
verifyToText 'one million and forty five', 1000045
verifyToText 'one million and fifteen', 1000015
verifyToText 'one billion, forty five thousand and one', 1000045001

View file

@ -0,0 +1,36 @@
import Data.List (intercalate, unfoldr)
spellInteger :: Integer -> String
spellInteger n
| n < 0 = "negative " ++ spellInteger (-n)
| 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 = intercalate ", " $ map big $ reverse $
filter ((/= 0) . snd) $ zip [0..] $ unfoldr uff n
where nonzero :: Char -> Integer -> String
nonzero _ 0 = ""
nonzero c n = c : spellInteger n
uff :: Integer -> Maybe (Integer, Integer)
uff 0 = Nothing
uff n = Just $ uncurry (flip (,)) $ n `divMod` 1000
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"]

View file

@ -0,0 +1,70 @@
SUBROUTINE NumberToWords(number)
CHARACTER outP*255, small*130, tens*80, big*80
REAL :: decimal_places = 7
INIT( APPENDIX("#literals"), small, tens, big)
num = ABS( INT(number) )
order = 0
outP = ' '
DO i = 1, num + 1
tmp = MOD(num, 100)
IF(tmp > 19) THEN
EDIT(Text=tens, ITeM=INT(MOD(tmp/10, 10)), Parse=medium)
IF( MOD(tmp, 10) ) THEN
EDIT(Text=small, ITeM=MOD(tmp,10)+1, Parse=mini)
outP = medium // '-' // mini // ' ' // outP
ELSE
outP = medium // ' ' // outP
ENDIF
ELSEIF(tmp > 0) THEN
EDIT(Text=small, ITeM=tmp+1, Parse=mini)
outP = mini // ' '// outP
ELSEIF(number == 0) THEN
outP = 'zero'
ENDIF
tmp = INT(MOD(num, 1000) / 100)
IF(tmp) THEN
EDIT(Text=small, ITeM=tmp+1, Parse=oneto19)
outP = oneto19 // ' hundred ' // outP
ENDIF
num = INT(num /1000)
IF( num == 0) THEN
IF(number < 0) outP = 'minus ' // outP
fraction = ABS( MOD(number, 1) )
IF(fraction) WRITE(Text=outP, APPend) ' point'
DO j = 1, decimal_places
IF( fraction >= 10^(-decimal_places) ) THEN
num = INT( 10.01 * fraction )
EDIT(Text=small, ITeM=num+1, Parse=digit)
WRITE(Text=outP, APPend) ' ', digit
fraction = 10*fraction - num
ENDIF
ENDDO
OPEN(FIle="temp.txt", APPend)
WRITE(FIle="temp.txt", Format='F10, " = ", A', CLoSe=1) number, outP
RETURN
ENDIF
order = order + 1
EDIT(Text=big, ITeM=order, Parse=kilo)
IF( MOD(num, 1000) ) outP = kilo // ' and '// outP
ENDDO
END
CALL NumberToWords( 0 )
CALL NumberToWords( 1234 )
CALL NumberToWords( 1234/100 )
CALL NumberToWords( 10000000 + 1.2 )
CALL NumberToWords( 2^15 )
CALL NumberToWords( 0.001 )
CALL NumberToWords( -EXP(1) )
#literals
SMALL= zero one two three four five six seven eight nine ten &
eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen
TENS=ten twenty thirty forty fifty sixty seventy eighty ninety
BIG=thousand million billion trillion quadrillion

View file

@ -0,0 +1,7 @@
0 = zero
1234 = one thousand and two hundred thirty-four
12.34 = twelve point three four
10000001.2 = ten million and one point two
32768 = thirty-two thousand and seven hundred sixty-eight
1E-3 = point zero zero one
-2.7182818 = minus two point seven one eight two eight one eight

View file

@ -0,0 +1,6 @@
link numbers # commas, spell
procedure main(arglist)
every x := !arglist do
write(commas(x), " -> ",spell(x))
end

View file

@ -0,0 +1,37 @@
procedure spell(n) #: spell out integer (short scale)
local m, i
static scale
initial {
scale := [ "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion","septillion"]
every scale[i := 1 to *scale ] := [ integer(repl("999",i + 1)), -3 * i, " "||scale[i] ]
push(scale,[999,2," hundred"])
}
n := integer(n) | stop(image(n)," is not an integer")
if n < 0 then return "negative " || spell(-n)
if n <= 12 then return {
"0zero,1one,2two,3three,4four,5five,6six,7seven,8eight,_
9nine,10ten,11eleven,12twelve," ? {
tab(find(n))
move(*n)
tab(find(","))
}
}
else if n <= 19 then return {
spell(n[2] || "0") ?
(if ="for" then "four" else tab(find("ty"))) || "teen"
}
else if n <= 99 then return {
"2twen,3thir,4for,5fif,6six,7seven,8eigh,9nine," ? {
tab(find(n[1]))
move(1)
tab(find(",")) || "ty" ||
(if n[2] ~= 0 then "-" || spell(n[2]) else "")
}
}
else if n <= scale[i := 1 to *scale,1] then return { # generalize based on scale
spell(n[1:scale[i,2]]) || scale[i,3] ||
(if (m := n[scale[i,2]:0]) ~= 0 then " and " || spell(m) else "")
}
else fail # really big
end

View file

@ -0,0 +1 @@
say 32767 in words;

View file

@ -0,0 +1 @@
say 2147483647 in words;

View file

@ -0,0 +1,24 @@
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

View file

@ -0,0 +1,64 @@
public class Int2Words {
static String[] small = {"one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
static String[] tens = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty",
"ninety"};
static String[] big = {"thousand", "million", "billion", "trillion"};
public static void main(String[] args) {
System.out.println(int2Text(900000001));
System.out.println(int2Text(1234567890));
System.out.println(int2Text(-987654321));
System.out.println(int2Text(0));
}
public static String int2Text(long number) {
long num = 0;
String outP = "";
int unit = 0;
long tmpLng1 = 0;
if (number == 0) {
return "zero";
}
num = Math.abs(number);
for (;;) {
tmpLng1 = num % 100;
if (tmpLng1 >= 1 && tmpLng1 <= 19) {
outP = small[(int) tmpLng1 - 1] + " " + outP;
} else if (tmpLng1 >= 20 && tmpLng1 <= 99) {
if (tmpLng1 % 10 == 0) {
outP = tens[(int) (tmpLng1 / 10) - 2] + " " + outP;
} else {
outP = tens[(int) (tmpLng1 / 10) - 2] + "-"
+ small[(int) (tmpLng1 % 10) - 1] + " " + outP;
}
}
tmpLng1 = (num % 1000) / 100;
if (tmpLng1 != 0) {
outP = small[(int) tmpLng1 - 1] + " hundred " + outP;
}
num /= 1000;
if (num == 0) {
break;
}
tmpLng1 = num % 1000;
if (tmpLng1 != 0) {
outP = big[unit] + " " + outP;
}
unit++;
}
if (number < 0) {
outP = "negative " + outP;
}
return outP.trim();
}
}

View file

@ -0,0 +1,18 @@
public class NumberToWordsConverter { // works upto 9999999
final private static String[] units = {"Zero","One","Two","Three","Four",
"Five","Six","Seven","Eight","Nine","Ten",
"Eleven","Twelve","Thirteen","Fourteen","Fifteen",
"Sixteen","Seventeen","Eighteen","Nineteen"};
final private static String[] tens = {"","","Twenty","Thirty","Forty","Fifty",
"Sixty","Seventy","Eighty","Ninety"};
public static String convert(Integer i) {
//
if( i < 20) return units[i];
if( i < 100) return tens[i/10] + ((i % 10 > 0)? " " + convert(i % 10):"");
if( i < 1000) return units[i/100] + " Hundred" + ((i % 100 > 0)?" and " + convert(i % 100):"");
if( i < 1000000) return convert(i / 1000) + " Thousand " + ((i % 1000 > 0)? " " + convert(i % 1000):"") ;
return convert(i / 1000000) + " Million " + ((i % 1000000 > 0)? " " + convert(i % 1000000):"") ;
}
}

View file

@ -0,0 +1,43 @@
DEFINE units ==
[ "zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten"
"eleven" "twelve" "thirteen" "fourteen" "fifteen" "sixteen" "seventeen"
"eighteen" "nineteen" ];
tens ==
[ "ten" "twenty" "thirty" "forty" "fifty" "sixty" "seventy" "eighty" "ninety" ];
convert6 ==
[1000000 <]
[1000 div swap convert " thousand " putchars convert3]
[1000000 div swap convert " million " putchars convert3]
ifte;
convert5 ==
[null]
[]
[" and " putchars convert]
ifte;
convert4 ==
[1000 <]
[100 div swap units of putchars " hundred" putchars convert5]
[convert6]
ifte;
convert3 ==
[null]
[]
[32 putch convert]
ifte;
convert2 ==
[100 <]
[10 div swap pred tens of putchars convert3]
[convert4]
ifte;
convert ==
[20 <]
[units of putchars]
[convert2]
ifte.

View file

@ -0,0 +1,28 @@
make "numbers {one two three four five six seven eight nine ten
eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen}
make "tens {twenty thirty forty fifty sixty seventy eighty ninety}@2
make "thou [[] thousand million billion trillion] ; expand as desired
to to.english.thou :n :thou
if :n = 0 [output []]
if :n < 20 [output sentence item :n :numbers first :thou]
if :n < 100 [output (sentence item int :n/10 :tens
to.english.thou modulo :n 10 [[]]
first :thou)]
if :n < 1000 [output (sentence item int :n/100 :numbers
"hundred
to.english.thou modulo :n 100 [[]]
first :thou)]
output (sentence to.english.thou int :n/1000 butfirst :thou
to.english.thou modulo :n 1000 :thou)
end
to to.english :n
if :n = 0 [output "zero]
if :n > 0 [output to.english.thou :n :thou]
[output sentence "negative to.english.thou minus :n :thou]
end
print to.english 1234567 ; one million two hundred thirty four thousand five hundred sixty seven

View file

@ -0,0 +1,37 @@
words = {"one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine "}
levels = {"thousand ", "million ", "billion ", "trillion ", "quadrillion ", "quintillion ", "sextillion ", "septillion ", "octillion ", [0] = ""}
iwords = {"ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety "}
twords = {"eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen "}
function digits(n)
local i, ret = -1
return function()
i, ret = i + 1, n % 10
if n > 0 then
n = math.floor(n / 10)
return i, ret
end
end
end
level = false
function getname(pos, dig) --stateful, but effective.
level = level or pos % 3 == 0
if(dig == 0) then return "" end
local name = (pos % 3 == 1 and iwords[dig] or words[dig]) .. (pos % 3 == 2 and "hundred " or "")
if(level) then name, level = name .. levels[math.floor(pos / 3)], false end
return name
end
local val, vword = io.read() + 0, ""
for i, v in digits(val) do
vword = getname(i, v) .. vword
end
for i, v in ipairs(words) do
vword = vword:gsub("ty " .. v, "ty-" .. v)
vword = vword:gsub("ten " .. v, twords[i])
end
if #vword == 0 then print "zero" else print(vword) end

View file

@ -0,0 +1,55 @@
fn NumberToWord myNum = (
local Result = ""
while myNum != 0 do (
Result += case of (
(myNum >= 1000):(myNum -= 1000; "one thousand")
(myNum > 900): (myNum -= 900 ; "nine hundred and")
(myNum == 900): (myNum -= 900 ; "nine hundred")
(myNum > 800): (myNum -= 800 ; "eight hundred and")
(myNum == 800): (myNum -= 900 ; "eight hundred")
(myNum > 700): (myNum -= 700 ; "seven hundred and")
(myNum == 700): (myNum -= 900 ; "seven hundred")
(myNum > 600): (myNum -= 600 ; "six hundred and")
(myNum == 600): (myNum -= 900 ; "six hundred")
(myNum > 500): (myNum -= 500 ; "five hundred and")
(myNum == 500): (myNum -= 900 ; "five hundred")
(myNum > 400): (myNum -= 400 ; "four hundred and")
(myNum == 400): (myNum -= 900 ; "four hundred")
(myNum > 300): (myNum -= 300 ; "three hundred and")
(myNum == 300): (myNum -= 900 ; "three hundred")
(myNum > 200): (myNum -= 200 ; "two hundred and")
(myNum == 200): (myNum -= 900 ; "two hundred")
(myNum > 100): (myNum -= 100 ; "one hundred and")
(myNum == 100): (myNum -= 100 ; "one hundred")
(myNum >= 90): (myNum -= 90 ; "ninety")
(myNum >= 80): (myNum -= 80 ; "eighty")
(myNum >= 70): (myNum -= 70 ; "seventy")
(myNum >= 60): (myNum -= 60 ; "sixty")
(myNum >= 50): (myNum -= 50 ; "fifty")
(myNum >= 40): (myNum -= 40 ; "fourty")
(myNum >= 30): (myNum -= 30 ; "thirty")
(myNum >= 20): (myNum -= 20 ; "twenty")
(myNum >= 19): (myNum -= 19 ; "nineteen")
(myNum >= 18): (myNum -= 18 ; "eighteen")
(myNum >= 17): (myNum -= 17 ; "seventeen")
(myNum >= 16): (myNum -= 16 ; "sixteen")
(myNum >= 15): (myNum -= 15 ; "fifteen")
(myNum >= 14): (myNum -= 14 ; "fourteen")
(myNum >= 13): (myNum -= 13 ; "thirteen")
(myNum >= 12): (myNum -= 12 ; "twelve")
(myNum >= 11): (myNum -= 11 ; "eleven")
(myNum >= 10): (myNum -= 10 ; "ten")
(myNum >= 9): (myNum -= 9 ; "nine")
(myNum >= 8): (myNum -= 8 ; "eight")
(myNum >= 7): (myNum -= 7 ; "seven")
(myNum >= 6): (myNum -= 6 ; "six")
(myNum >= 5): (myNum -= 5 ; "five")
(myNum >= 4): (myNum -= 4 ; "four")
(myNum >= 3): (myNum -= 3 ; "three")
(myNum >= 2): (myNum -= 2 ; "two")
(myNum >= 1): (myNum -= 1 ; "one")
)
if myNum != 0 then result += " "
)
result
)

View file

@ -0,0 +1 @@
NumberToWord(123)

View file

@ -0,0 +1,24 @@
small = "zero"["one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen",
"nineteen"]; tens = # <> "-" & /@ {"twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"};
big = Prepend[
" " <> # & /@ {"thousand", "million", "billion", "trillion",
"quadrillion", "quintillion", "sextillion", "septillion",
"octillion", "nonillion", "decillion", "undecillion",
"duodecillion", "tredecillion"}, ""];
name[n_Integer] := "negative " <> name[-n] /; n < 0;
name[n_Integer] := small[[n]] /; 0 <= n < 20;
name[n_Integer] :=
StringTrim[tens[[#1 - 1]] <> small[[#2]] & @@ IntegerDigits[n],
"-zero"] /; 10 <= n < 100;
name[n_Integer] :=
StringTrim[
small[[#1]] <> " hundred and " <> name@#2 & @@
IntegerDigits[n, 100], " and zero"] /; 100 <= n < 1000;
name[n_Integer] :=
StringJoin@
Riffle[Select[
MapThread[StringJoin, {name /@ #, Reverse@big[[;; Length@#]]}] &@
IntegerDigits[n, 1000], StringFreeQ[#, "zero"] &], ","];

View file

@ -0,0 +1,57 @@
let div_mod n d = (n / d, n mod d)
let join = String.concat ", " ;;
let rec nonzero = function
| _, 0 -> ""
| c, n -> c ^ (spell_integer n)
and tens n =
[| ""; ""; "twenty"; "thirty"; "forty"; "fifty";
"sixty"; "seventy"; "eighty"; "ninety" |].(n)
and small n =
[| "zero"; "one"; "two"; "three"; "four"; "five";
"six"; "seven"; "eight"; "nine"; "ten"; "eleven";
"twelve"; "thirteen"; "fourteen"; "fifteen";
"sixteen";"seventeen"; "eighteen"; "nineteen" |].(n)
and bl = [| ""; ""; "m"; "b"; "tr"; "quadr"; "quint";
"sext"; "sept"; "oct"; "non"; "dec" |]
and big = function
| 0, n -> (spell_integer n)
| 1, n -> (spell_integer n) ^ " thousand"
| e, n -> (spell_integer n) ^ " " ^ bl.(e) ^ "illion"
and uff acc = function
| 0 -> List.rev acc
| n ->
let a, b = div_mod n 1000 in
uff (b::acc) a
and spell_integer = function
| n when n < 0 -> invalid_arg "spell_integer: negative input"
| n when n < 20 -> small n
| n when n < 100 ->
let a, b = div_mod n 10 in
(tens a) ^ nonzero("-", b)
| n when n < 1000 ->
let a, b = div_mod n 100 in
(small a) ^ " hundred" ^ nonzero(" ", b)
| n ->
let seg = (uff [] n) in
let _, segn =
(* just add the index of the item in the list *)
List.fold_left
(fun (i,acc) v -> (succ i, (i,v)::acc))
(0,[])
seg
in
let fsegn =
(* remove right part "zero" *)
List.filter
(function (_,0) -> false | _ -> true)
segn
in
join(List.map big fsegn)
;;

View file

@ -0,0 +1,93 @@
class NumberNames {
small : static : String[];
tens : static : String[];
big : static : String[];
function : Main(args : String[]) ~ Nil {
small := ["one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
tens := ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"];
big := ["thousand", "million", "billion", "trillion"];
Int2Text(900000001)->PrintLine();
Int2Text(1234567890)->PrintLine();
Int2Text(-987654321)->PrintLine();
Int2Text(0)->PrintLine();
}
function : native : Int2Text(number : Int) ~ String {
num := 0;
outP := "";
unit := 0;
tmpLng1 := 0;
if (number = 0) {
return "zero";
};
num := number->Abs();
while(true) {
tmpLng1 := num % 100;
if (tmpLng1 >= 1 & tmpLng1 <= 19) {
tmp := String->New();
tmp->Append(small[tmpLng1 - 1]);
tmp->Append(" ");
tmp->Append(outP);
outP := tmp;
}
else if (tmpLng1 >= 20 & tmpLng1 <= 99) {
if (tmpLng1 % 10 = 0) {
tmp := String->New();
tmp->Append(tens[(tmpLng1 / 10) - 2]);
tmp->Append(" ");
tmp->Append(outP);
outP := tmp;
}
else {
tmp := String->New();
tmp->Append(tens[(tmpLng1 / 10) - 2]);
tmp->Append( "-");
tmp->Append(small[(tmpLng1 % 10) - 1]);
tmp->Append(" ");
tmp->Append(outP);
outP := tmp;
};
};
tmpLng1 := (num % 1000) / 100;
if (tmpLng1 <> 0) {
tmp := String->New();
tmp->Append(small[tmpLng1 - 1]);
tmp->Append(" hundred ");
tmp->Append(outP);
outP := tmp;
};
num /= 1000;
if (num = 0) {
break;
};
tmpLng1 := num % 1000;
if (tmpLng1 <> 0) {
tmp := String->New();
tmp->Append(big[unit]);
tmp->Append(" ");
tmp->Append(outP);
outP := tmp;
};
unit+=1;
};
if (number < 0) {
tmp := String->New();
tmp->Append("negative ");
tmp->Append(outP);
outP := tmp;
};
return outP->Trim();
}
}

View file

@ -0,0 +1,34 @@
Eng(n:int)={
my(tmp,s="");
if (n >= 1000000,
tmp = n\1000000;
s = Str(Eng(tmp), " million");
n -= tmp * 1000000;
if (!n, return(s));
s = Str(s, " ")
);
if (n >= 1000,
tmp = n\1000;
s = Str(Eng(tmp), " thousand");
n -= tmp * 1000;
if (!n, return(s));
s = Str(s, " ")
);
if (n >= 100,
tmp = n\100;
s = Str(Edigit(tmp), " hundred");
n -= tmp * 100;
if (!n, return(s));
s = Str(s, " ")
);
if (n < 20,
return (Str(s, ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "ninteen"][n]))
);
tmp = n\10;
s = Str(s, [0, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"][tmp]);
n -= tmp * 10;
if (n, Str(s, "-", Edigit(n)), s)
};
Edigit(n)={
["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"][n]
};

View file

@ -0,0 +1,57 @@
$orderOfMag = array('Hundred', 'Thousand,', 'Million,', 'Billion,', 'Trillion,');
$smallNumbers = array('Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen');
$decades = array('', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety');
function NumberToEnglish($num, $count = 0){
global $orderOfMag, $smallNumbers, $decades;
$isLast = true;
$str = '';
if ($num < 0){
$str = 'Negative ';
$num = abs($num);
}
(int) $thisPart = substr((string) $num, -3);
if (strlen((string) $num) > 3){
// Number still too big, work on a smaller chunk
$str .= NumberToEnglish((int) substr((string) $num, 0, strlen((string) $num) - 3), $count + 1);
$isLast = false;
}
// do translation stuff
if (($count == 0 || $isLast) && ($str == '' || $str == 'Negative '))
// This is either a very small number or the most significant digits of the number. Either way we don't want a preceeding "and"
$and = '';
else
$and = ' and ';
if ($thisPart > 99){
// Hundreds part of the number chunk
$str .= ($isLast ? '' : ' ') . "{$smallNumbers[$thisPart/100]} {$orderOfMag[0]}";
if(($thisPart %= 100) == 0){
// There is nothing else to do for this chunk (was a multiple of 100)
$str .= " {$orderOfMag[$count]}";
return $str;
}
$and = ' and '; // Set up our and string to the word "and" since there is something in the hundreds place of this chunk
}
if ($thisPart >= 20){
// Tens part of the number chunk
$str .= "{$and}{$decades[$thisPart /10]}";
$and = ' '; // Make sure we don't have any extranious "and"s
if(($thisPart %= 10) == 0)
return $str . ($count != 0 ? " {$orderOfMag[$count]}" : '');
}
if ($thisPart < 20 && $thisPart > 0)
// Ones part of the number chunk
return $str . "{$and}{$smallNumbers[(int) $thisPart]} " . ($count != 0 ? $orderOfMag[$count] : '');
elseif ($thisPart == 0 && strlen($thisPart) == 1)
// The number is zero
return $str . "{$smallNumbers[(int)$thisPart]}";
}

View file

@ -0,0 +1,6 @@
NumberToEnglish(0);
NumberToEnglish(12);
NumberToEnglish(123);
NumberToEnglish(1234567890123);
NumberToEnglish(65535);
NumberToEnglish(-54321);

View file

@ -0,0 +1,54 @@
declare integer_names (0:20) character (9) varying static initial
('zero', 'one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve',
'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen',
'eighteen', 'nineteen', 'twenty' );
declare x(10) character (7) varying static initial
('ten', 'twenty', 'thirty', 'fourty', 'fifty',
'sixty', 'seventy', 'eighty', 'ninety', 'hundred');
declare y(0:5) character (10) varying static initial
('', '', ' thousand ', ' million ', ' billion ', ' trillion ');
declare (i, j, m, t) fixed binary (31);
declare (units, tens, hundreds, thousands) fixed binary (7);
declare (h, v, value) character (200) varying;
declare (d, k, n) fixed decimal (15);
declare three_digits fixed decimal (3);
value = '';
i = 5;
k = n;
do d = 1000000000000 repeat d/1000 while (d > 0);
i = i - 1;
three_digits = k/d;
k = mod(k, d);
if three_digits = 0 then iterate;
units = mod(three_digits, 10);
t = three_digits / 10;
tens = mod(t, 10);
hundreds = three_digits / 100;
m = mod(three_digits, 100);
if m <= 20 then
v = integer_names(m);
else if units = 0 then
v = '';
else
v = integer_names(units);
if tens >= 2 & units ^= 0 then
v = x(tens) || v;
else if tens > 2 & units = 0 then
v = v || x(tens);
if units + tens = 0 then
if n > 0 then v = '';
if hundreds > 0 then
h = integer_names(hundreds) || ' hundred ';
else
h = '';
if three_digits > 100 & (tens + units > 0) then
v = 'and ' || v;
if i = 1 & value ^= '' & three_digits <= 9 then
v = 'and ' || v;
value = value ||h || v || y(i);
end;
put skip edit (trim(N), ' = ', value) (a);

View file

@ -0,0 +1,82 @@
program NumberNames(output);
const
smallies: array[1..19] of string =
('one', 'two', 'three', 'four', 'five', 'six',
'seven', 'eight', 'nine', 'ten', 'eleven',
'twelve', 'thirteen', 'fourteen', 'fifteen',
'sixteen', 'seventeen', 'eighteen', 'nineteen');
tens: array[2..9] of string =
('twenty', 'thirty', 'forty', 'fifty',
'sixty', 'seventy', 'eighty', 'ninety');
function domaxies(number: int64): string;
const
maxies: array[0..5] of string =
(' thousand', ' million', ' billion',
' trillion', ' quadrillion', ' quintillion');
begin
domaxies := '';
if number >= 0 then
domaxies := maxies[number];
end;
function doHundreds( number: int64): string;
begin
doHundreds := '';
if number > 99 then
begin
doHundreds := smallies[number div 100];
doHundreds := doHundreds + ' hundred';
number := number mod 100;
if number > 0 then
doHundreds := doHundreds + ' and ';
end;
if number >= 20 then
begin
doHundreds := doHundreds + tens[number div 10];
number := number mod 10;
if number > 0 then
doHundreds := doHundreds + '-';
end;
if (0 < number) and (number < 20) then
doHundreds := doHundreds + smallies[number];
end;
function spell(number: int64): string;
var
scaleFactor: int64 = 1000000000000000000;
maxieStart, h: int64;
begin
spell := '';
maxieStart := 5;
if number < 20 then
spell := smallies[number];
while scaleFactor > 0 do
begin
if number > scaleFactor then
begin
h := number div scaleFactor;
spell := spell + doHundreds(h) + domaxies(maxieStart);
number := number mod scaleFactor;
if number > 0 then
spell := spell + ', ';
end;
scaleFactor := scaleFactor div 1000;
dec(maxieStart);
end;
end;
begin
writeln(99, ': ', spell(99));
writeln(234, ': ', spell(234));
writeln(7342, ': ', spell(7342));
writeln(32784, ': ', spell(32784));
writeln(234345, ': ', spell(234345));
writeln(2343451, ': ', spell(2343451));
writeln(23434534, ': ', spell(23434534));
writeln(234345456, ': ', spell(234345456));
writeln(2343454569, ': ', spell(2343454569));
writeln(2343454564356, ': ', spell(2343454564356));
writeln(2345286538456328, ': ', spell(2345286538456328));
end.

View file

@ -0,0 +1,34 @@
constant @I = <zero one two three four five six seven eight nine
ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen>;
constant @X = <0 X twenty thirty forty fifty sixty seventy eighty ninety>;
constant @C = @I X~ ' hundred';
constant @M = (<0 thousand>,
((<m b tr quadr quint sext sept oct non>,
(map { ('', <un duo tre quattuor quin sex septen octo novem>).flat X~ $_ },
<dec vigint trigint quadragint quinquagint sexagint septuagint octogint nonagint>),
'cent').flat X~ 'illion')).flat;
sub int-name ($num) {
if $num.substr(0,1) eq '-' { return "negative {int-name($num.substr(1))}" }
if $num eq '0' { return @I[0] }
my $m = 0;
return join ', ', reverse gather for $num.flip.comb(/\d ** 1..3/) {
my ($i,$x,$c) = .comb;
if $i or $x or $c {
take join ' ', gather {
if $c { take @C[$c] }
if $x and $x == 1 { take @I[$i+10] }
else {
if $x { take @X[$x] }
if $i { take @I[$i] }
}
take @M[$m] // die "WOW! ZILLIONS!\n" if $m;
}
}
$m++;
}
}
while '' ne (my $n = prompt("Number: ")) {
say int-name($n);
}

View file

@ -0,0 +1,3 @@
use Lingua::EN::Numbers 'num2en';
print num2en(123456789), "\n";

View file

@ -0,0 +1,22 @@
(de numName (N)
(cond
((=0 N) "zero")
((lt0 N) (pack "minus " (numName (- N))))
(T (numNm N)) ) )
(de numNm (N)
(cond
((=0 N))
((> 14 N)
(get '("one" "two" "three" "four" "five" "six" "seven" "eight" "nine" "ten" "eleven" "twelve" "thirteen") N) )
((= 15 N) "fifteen")
((= 18 N) "eighteen")
((> 20 N) (pack (numNm (% N 10)) "teen"))
((> 100 N)
(pack
(get '("twen" "thir" "for" "fif" "six" "seven" "eigh" "nine") (dec (/ N 10)))
"ty"
(unless (=0 (% N 10))
(pack "-" (numNm (% N 10))) ) ) )
((rank N '((100 . "hundred") (1000 . "thousand") (1000000 . "million")))
(pack (numNm (/ N (car @))) " " (cdr @) " " (numNm (% N (car @)))) ) ) )

View file

@ -0,0 +1,68 @@
FUNCTION int2Text (number AS QUAD) AS STRING
IF 0 = number THEN
FUNCTION = "zero"
EXIT FUNCTION
END IF
DIM num AS QUAD, outP AS STRING, unit AS LONG
DIM tmpLng1 AS QUAD
DIM small(1 TO 19) AS STRING, tens(7) AS STRING, big(5) AS STRING
DIM tmpInt AS LONG, dcnt AS LONG
ARRAY ASSIGN small() = "one", "two", "three", "four", "five", "six", _
"seven", "eight", "nine", "ten", "eleven", _
"twelve", "thirteen", "fourteen", "fifteen", _
"sixteen", "seventeen", "eighteen", "nineteen"
ARRAY ASSIGN tens() = "twenty", "thirty", "forty", "fifty", "sixty", _
"seventy", "eighty", "ninety"
ARRAY ASSIGN big() = "thousand", "million", "billion", "trillion", _
"quadrillion", "quintillion"
num = ABS(number)
DO
tmpLng1 = num MOD 100
SELECT CASE tmpLng1
CASE 1 TO 19
outP = small(tmpLng1) + " " + outP
CASE 20 TO 99
SELECT CASE tmpLng1 MOD 10
CASE 0
outP = tens((tmpLng1 \ 10) - 2) + " " + outP
CASE ELSE
outP = tens((tmpLng1 \ 10) - 2) + "-" + small(tmpLng1 MOD 10) + " " + outP
END SELECT
END SELECT
tmpLng1 = (num MOD 1000) \ 100
IF tmpLng1 THEN
outP = small(tmpLng1) + " hundred " + outP
END IF
num = num \ 1000
IF num < 1 THEN EXIT DO
tmpLng1 = num MOD 1000
IF tmpLng1 THEN outP = big(unit) + " " + outP
unit = unit + 1
LOOP
IF number < 0 THEN outP = "negative " + outP
FUNCTION = RTRIM$(outP)
END FUNCTION
FUNCTION PBMAIN () AS LONG
DIM n AS QUAD
#IF %DEF(%PB_CC32)
INPUT "Gimme a number! ", n
#ELSE
n = VAL(INPUTBOX$("Gimme a number!", "Now!"))
#ENDIF
? int2Text(n)
END FUNCTION

View file

@ -0,0 +1,120 @@
DataSection
numberNames:
;small
Data.s "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"
Data.s "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
;tens
Data.s "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
;big, non-Chuquet system
Data.s "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion"
Data.s "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion"
Data.s "tredecillion"
EndDataSection
Procedure.s numberWords(number.s)
;handles integers from -1E45 to +1E45
Static isInitialized = #False
Static Dim small.s(19)
Static Dim tens.s(9)
Static Dim big.s(14)
If Not isInitialized
Restore numberNames
For i = 1 To 19
Read.s small(i)
Next
For i = 2 To 9
Read.s tens(i)
Next
For i = 1 To 14
Read.s big(i)
Next
isInitialized = #True
EndIf
For i = 1 To Len(number)
If Not FindString("- 0123456789", Mid(number,i,1), 1)
number = Left(number, i - 1) ;trim number to the last valid character
Break ;exit loop
EndIf
Next
Protected IsNegative = #False
number = Trim(number)
If Left(number,1) = "-"
IsNegative = #True
number = Trim(Mid(number, 2))
EndIf
If CountString(number, "0") = Len(number)
ProcedureReturn "zero"
EndIf
If Len(number) > 45
ProcedureReturn "Number is too big!"
EndIf
Protected num.s = number, output.s, unit, unitOutput.s, working
Repeat
working = Val(Right(num, 2))
unitOutput = ""
Select working
Case 1 To 19
unitOutput = small(working)
Case 20 To 99
If working % 10
unitOutput = tens(working / 10) + "-" + small(working % 10)
Else
unitOutput = tens(working / 10)
EndIf
EndSelect
working = Val(Right(num, 3)) / 100
If working
If unitOutput <> ""
unitOutput = small(working) + " hundred " + unitOutput
Else
unitOutput = small(working) + " hundred"
EndIf
EndIf
If unitOutput <> "" And unit > 0
unitOutput + " " + big(unit)
If output <> ""
unitOutput + ", "
EndIf
EndIf
output = unitOutput + output
If Len(num) > 3
num = Left(num, Len(num) - 3)
unit + 1
Else
Break ;exit loop
EndIf
ForEver
If IsNegative
output = "negative " + output
EndIf
ProcedureReturn output
EndProcedure
Define n$
If OpenConsole()
Repeat
Repeat
Print("Give me an integer (or q to quit)! ")
n$ = Input()
Until n$ <> ""
If Left(Trim(n$),1) = "q"
Break ;exit loop
EndIf
PrintN(numberWords(n$))
ForEver
CloseConsole()
EndIf

View file

@ -0,0 +1,48 @@
def spell_integer(n):
tens = [None, None, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"]
small = ["zero", "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"]
bl = [None, None, "m", "b", "tr", "quadr",
"quint", "sext", "sept", "oct", "non", "dec"]
def nonzero(c, n):
return "" if n == 0 else c + spell_integer(n)
def big(e, n):
if e == 0:
return spell_integer(n)
elif e == 1:
return spell_integer(n) + " thousand"
else:
return spell_integer(n) + " " + bl[e] + "illion"
def base1000_rev(n):
# generates the value of the digits of n in base 1000
# (i.e. 3-digit chunks), in reverse.
while n != 0:
n, r = divmod(n, 1000)
yield r
if n < 0:
return "negative " + spell_integer(-n)
elif n < 20:
return small[n]
elif n < 100:
a, b = divmod(n, 10)
return tens[a] + nonzero("-", b)
elif n < 1000:
a, b = divmod(n, 100)
return small[a] + " hundred" + nonzero(" ", b)
else:
return ", ".join([big(e, x) for e, x in
enumerate(base1000_rev(n)) if x][::-1])
# example
print spell_integer(1278)
print spell_integer(1752)
print spell_integer(2010)

View file

@ -0,0 +1,59 @@
SMALL = %w(zero one two three four five six seven eight nine ten
eleven twelve thirteen fourteen fifteen sixteen seventeen
eighteen nineteen)
TENS = %w(wrong wrong twenty thirty forty fifty sixty seventy
eighty ninety)
BIG = [nil, "thousand"] +
%w( m b tr quadr quint sext sept oct non dec).map{ |p| "#{p}illion" }
def wordify number
if number < 0
"negative #{wordify -number}"
elsif number < 20
SMALL[number]
elsif number < 100
div, mod = number.divmod(10)
"#{TENS[div]}-#{wordify mod}".chomp("-zero")
elsif number < 1000
div, mod = number.divmod(100)
"#{wordify div} hundred and #{wordify mod}".chomp(" and zero")
else
# separate into 3-digit chunks
chunks = []
div = number
while div != 0
div, mod = div.divmod(1000)
chunks << mod # will store smallest to largest
end
if chunks.length > BIG.length
raise ArgumentError, "Integer value too large."
end
chunks.map{ |c| wordify c }.
zip(BIG). # zip pairs up corresponding elements from the two arrays
find_all { |c| c[0] != 'zero' }.
map{ |c| c.join ' '}. # join ["forty", "thousand"]
reverse.
join(', '). # join chunks
strip
end
end
[-1123, 0, 1, 20, 123, 200, 220, 1245, 2000, 2200, 2220, 467889, 23_000_467,
23_234_467, 2_235_654_234, 12_123_234_543_543_456,
123890812938219038290489327894327894723897432].each do |n|
print "#{n}: "
begin
puts "'#{wordify n}'"
rescue => e
puts "Error: #{e}"
end
end

View file

@ -0,0 +1,12 @@
$ include "seed7_05.s7i";
include "stdio.s7i";
include "wrinum.s7i";
const proc: main is func
local
var integer: number is 0;
begin
for number range 1 to 999999 do
writeln(str(ENGLISH, number));
end for;
end func;

View file

@ -0,0 +1,72 @@
proc int2words {n} {
if { ! [regexp -- {^(-?\d+)$} $n -> n]} {
error "not a decimal integer"
}
if {$n == 0} {
return zero
}
if {$n < 0} {
return "negative [int2words [expr {abs($n)}]]"
}
if {[string length $n] > 36} {
error "value too large to represent"
}
set groups [get_groups $n]
set l [llength $groups]
foreach group $groups {
incr l -1
# ensure any group with a leading zero is not treated as octal
set val [scan $group %d]
if {$val > 0} {
lappend result [group2words $val $l]
}
}
return [join $result ", "]
}
set small {"" one two three four five six seven eight nine ten eleven twelve
thirteen fourteen fifteen sixteen seventeen eighteen nineteen}
set tens {"" "" twenty thirty forty fifty sixty seventy eighty ninety}
set powers {"" thousand}
foreach p {m b tr quadr quint sext sept oct non dec} {lappend powers ${p}illion}
proc group2words {n level} {
global small tens powers
if {$n < 20} {
lappend result [lindex $small $n]
} elseif {$n < 100} {
lassign [divmod $n 10] a b
set result [lindex $tens $a]
if {$b > 0} {
append result - [lindex $small $b]
}
} else {
lassign [divmod $n 100] a b
lappend result [lindex $small $a] hundred
if {$b > 0} {
lappend result and [group2words $b 0]
}
}
return [join [concat $result [lindex $powers $level]]]
}
proc divmod {n d} {
return [list [expr {$n / $d}] [expr {$n % $d}]]
}
proc get_groups {num} {
# from http://wiki.tcl.tk/5000
while {[regsub {^([-+]?\d+)(\d\d\d)} $num {\1 \2} num]} {}
return [split $num]
}
foreach test {
0 -0 5 -5 10 25 99 100 101 999 1000 1008 1010 54321 1234567890
0x7F
123456789012345678901234567890123456
1234567890123456789012345678901234567
} {
catch {int2words $test} result
puts "$test -> $result"
}

View file

@ -0,0 +1,28 @@
Module Module1
Sub Main()
Dim i As Integer
Console.WriteLine("Enter a number")
i = Console.ReadLine()
Console.WriteLine(words(i))
Console.ReadLine()
End Sub
Function words(ByVal Number As Integer) As String
Dim small() As String = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
"eighteen", "nineteen"}
Dim tens() As String = {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}
Select Case Number
Case Is < 20
words = small(Number)
Case 20 To 99
words = tens(Number \ 10) + " " + small(Number Mod 10)
Case 100 To 999
words = small(Number \ 100) + " hundred " + IIf(((Number Mod 100) <> 0), "and ", "") + words(Number Mod 100)
Case 1000
words = "one thousand"
End Select
End Function
End Module

View file

@ -0,0 +1,60 @@
Option Explicit
Private small As Variant, tens As Variant, big As Variant
Sub Main()
small = Array("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", _
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", _
"eighteen", "nineteen")
tens = Array("twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety")
big = Array("thousand", "million", "billion")
Dim tmpInt As Long
tmpInt = Val(InputBox("Gimme a number!", "NOW!", Trim$(Year(Now)) & IIf(Month(Now) < 10, "0", "") & _
Trim$(Month(Now)) & IIf(Day(Now) < 10, "0", "") & Trim$(Day(Now))))
MsgBox int2Text$(tmpInt)
End Sub
Function int2Text$(number As Long)
Dim num As Long, outP As String, unit As Integer
Dim tmpLng1 As Long
If 0 = number Then
int2Text$ = "zero"
Exit Function
End If
num = Abs(number)
Do
tmpLng1 = num Mod 100
Select Case tmpLng1
Case 1 To 19
outP = small(tmpLng1 - 1) + " " + outP
Case 20 To 99
Select Case tmpLng1 Mod 10
Case 0
outP = tens((tmpLng1 \ 10) - 2) + " " + outP
Case Else
outP = tens((tmpLng1 \ 10) - 2) + "-" + small(tmpLng1 Mod 10) + " " + outP
End Select
End Select
tmpLng1 = (num Mod 1000) \ 100
If tmpLng1 Then
outP = small(tmpLng1 - 1) + " hundred " + outP
End If
num = num \ 1000
If num < 1 Then Exit Do
tmpLng1 = num Mod 1000
If tmpLng1 Then outP = big(unit) + " " + outP
unit = unit + 1
Loop
If number < 0 Then outP = "negative " & outP
int2Text$ = Trim$(outP)
End Function

View file

@ -0,0 +1,53 @@
code ChOut=8, CrLf=9, Text=12;
proc NumName(Dev, Num); \Output integer Num in prose to device Dev
int Dev, Num;
int OneTbl, TenTbl, ThoTbl, ThoPwr, I, Quot;
proc Out999(N); \Output number in range 0..999 (0 does nothing)
int N;
int Huns, Tens, Ones;
[Huns:= N/100; \0..9
N:= rem(0); \0..99
Tens:= N/10; \0..9
Ones:= rem(0); \0..9
if Huns # 0 then
[Text(Dev, OneTbl(Huns)); \1..9
Text(Dev, " hundred ")];
if Tens >= 2 then
[Text(Dev, TenTbl(Tens));
if Ones # 0 then
[ChOut(Dev, ^-); Text(Dev, OneTbl(Ones))];
]
else if N # 0 then Text(Dev, OneTbl(N)); \N = 1..19
];
[if Num = 0 then [Text(Dev, "zero"); return];
if Num < 0 then [Num:= -Num; Text(Dev, "minus ")];
OneTbl:=[0, "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
TenTbl:=[0, 0, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"];
ThoTbl:=[" billion ", " million ", " thousand "];
ThoPwr:= 1000000000;
for I:= 0 to 2 do
[Quot:= Num/ThoPwr;
Num:= rem(0);
if Quot # 0 then
[Out999(Quot); Text(Dev, ThoTbl(I))];
ThoPwr:= ThoPwr/1000;
];
Out999(Num);
];
[NumName(0, 0); CrLf(0);
NumName(0, 13); CrLf(0);
NumName(0, 789); CrLf(0);
NumName(0, -604_001); CrLf(0);
NumName(0, 1_000_000); CrLf(0);
NumName(0, 1_234_567_890); CrLf(0);
]