Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1 +1,3 @@
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.
Show how to spell out a number in English. <br>
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). <br>
Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.

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

@ -10,23 +10,23 @@ immutable huge = ["", ""] ~ ["m", "b", "tr", "quadr", "quint",
"sext", "sept", "oct", "non", "dec"]
.map!q{ a ~ "illion" }.array;
string spellBigInt(BigInt n) {
static string nonZero(string c, BigInt n, string connect="") {
return n == 0 ? "" : connect ~ c ~ n.spellBigInt;
string spellBigInt(BigInt n) pure /*nothrow @safe*/ {
static string nonZero(string c, BigInt n, string connect="") pure /*nothrow @safe*/ {
return (n == 0) ? "" : (connect ~ c ~ n.spellBigInt);
}
static string lastAnd(string num) {
if (num.canFind(",")) {
string pre = num.retro.find(",").retro[0 .. $ - 1];
static string lastAnd(string num) pure /*nothrow*/ @safe {
if (num.canFind(',')) {
string pre = num.retro.find(',').retro[0 .. $ - 1];
string last = num[pre.length + 1 .. $];
if (!last.canFind(" and "))
last = " and" ~ last;
num = pre ~ "," ~ last;
num = pre ~ ',' ~ last;
}
return num;
}
static string big(in uint e, BigInt n) {
static string big(in uint e, in BigInt n) pure /*nothrow @safe*/ {
switch (e) {
case 0: return n.spellBigInt;
case 1: return n.spellBigInt ~ " thousand";
@ -39,19 +39,19 @@ string spellBigInt(BigInt n) {
} else if (n < 20) {
return small[n.toInt];
} else if (n < 100) {
BigInt a = n / 10;
BigInt b = n % 10;
immutable BigInt a = n / 10;
immutable BigInt b = n % 10;
return tens[a.toInt] ~ nonZero("-", b);
} else if (n < 1000) {
BigInt a = n / 100;
BigInt b = n % 100;
} else if (n < 1_000) {
immutable BigInt a = n / 100;
immutable BigInt b = n % 100;
return small[a.toInt] ~ " hundred" ~ nonZero(" ", b, " and");
} else {
string[] bigs;
uint e = 0;
while (n != 0) {
BigInt r = n % 1000;
n /= 1000;
immutable BigInt r = n % 1_000;
n /= 1_000;
if (r != 0)
bigs ~= big(e, r);
e++;
@ -63,7 +63,7 @@ string spellBigInt(BigInt n) {
version(number_names_main) {
void main() {
foreach (n; [0, -3, 5, -7, 11, -13, 17, -19, 23, -29])
foreach (immutable n; [0, -3, 5, -7, 11, -13, 17, -19, 23, -29])
writefln("%+4d -> %s", n, n.BigInt.spellBigInt);
writeln;

View file

@ -1,55 +1,37 @@
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 += " "
fn numToEng num =
(
num = num as integer -- convert to int
local originalNumber = num -- store the initial value, to check if it was negative afterwards
num = abs num -- make positive
local numStr = num as string -- store as string to check the length
local nonFirstDigits = (if numStr.count > 3 then ((substring numStr ((if mod numStr.count 3 ==0 then 3 else mod numStr.count 3)+1) -1)) else "0") -- this is the string of the number without the beginning, i.e 123456 will give 456, 12035 will give 2035
local singleDigits = #("One","Two","Three","Four","Five","Six","Seven","Eight","Nine")
local ElevenTwenty = #("Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen")
local tens = #("Ten","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety")
local big = #("Hundred","Thousand","Million","Billion")
local ret = "" -- this is the value to be returned
case of
(
(num == 0 ): ret += "Zero" -- number is zero
(num < 10): ret += singleDigits[num] -- number is not and smaller than 10
(num == 10): ret += tens[1] -- number is 10
(num < 20): ret += elevenTwenty[abs(10-num)] -- number is between 11 and 19
(num <= 90 and mod num 10 == 0): ret += tens[num/10] -- number is >= 20 and <= 90 and is dividable by 10
(num < 100): ret += (numToEng (floor(num/10.0)*10) +" "+ numtoEng (num-(floor(num/10.0))*10)) -- number is >= 20, < 100 and is not dividable by 10
(num < 1000): ret += (singledigits[floor(num/100) as integer] + " "+big[1]+ (if mod num 100 != 0 then (" and "+numtoeng (num-(floor(num/100.0)*100))) else "")) -- number is >= 100, < 1000
(num >= 1000): ret += -- number is >= 1000
(
numtoeng (substring numStr 1 (if mod numStr.count 3 ==0 then 3 else mod numStr.count 3)) + \
" " + big[1+((numStr.count-1)/3)] + (if nonFirstDigits as integer == 0 then "" else (if nonFirstDigits as integer < 100 then " and " else ", ")) + \
(if (mod num 1000 == 0) then "" else (numtoeng nonFirstDigits))
)
)
result
if originalNumber < 0 and (substring ret 1 8) != "Negative" do ret = ("Negative "+ret) -- if number is negative
ret = (toupper ret[1]) + (tolower (substring ret 2 -1)) -- make the first char uppercase and rest lowercase
return ret
)

View file

@ -1 +1,14 @@
NumberToWord(123)
numtoeng 0
"Zero"
numtoeng 50
"Fifty"
numtoeng 123
"One hundred and twenty three"
numtoeng -4235
"Negative four thousand, two hundred and thirty five"
numtoeng 98273
"Ninety eight thousand, two hundred and seventy three"
numtoeng -92836152
"Negative ninety two million, eight hundred and thirty six thousand, one hundred and fifty two"
numtoeng 421752302
"Four hundred and twenty one million, seven hundred and fifty two thousand, three hundred and two"

View file

@ -0,0 +1,16 @@
#import <Foundation/Foundation.h>
int main() {
@autoreleasepool {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterSpellOutStyle;
numberFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
for (NSNumber *n in @[@900000001, @1234567890, @-987654321, @0, @3.14]) {
NSLog(@"%@", [numberFormatter stringFromNumber:n]);
}
}
return 0;
}

View file

@ -8,21 +8,21 @@ TENS = %w(wrong wrong twenty thirty forty fifty sixty seventy
BIG = [nil, "thousand"] +
%w( m b tr quadr quint sext sept oct non dec).map{ |p| "#{p}illion" }
def wordify number
if number < 0
case
when number < 0
"negative #{wordify -number}"
elsif number < 20
when number < 20
SMALL[number]
elsif number < 100
when number < 100
div, mod = number.divmod(10)
"#{TENS[div]}-#{wordify mod}".chomp("-zero")
TENS[div] + (mod==0 ? "" : "-#{wordify mod}")
elsif number < 1000
when number < 1000
div, mod = number.divmod(100)
"#{wordify div} hundred and #{wordify mod}".chomp(" and zero")
"#{SMALL[div]} hundred" + (mod==0 ? "" : " and #{wordify mod}")
else
# separate into 3-digit chunks
@ -30,26 +30,27 @@ def wordify number
div = number
while div != 0
div, mod = div.divmod(1000)
chunks << mod # will store smallest to largest
chunks << mod # will store smallest to largest
end
if chunks.length > BIG.length
raise ArgumentError, "Integer value too large."
end
raise ArgumentError, "Integer value too large." if chunks.size > BIG.size
chunks.map{ |c| wordify c }.
zip(BIG). # zip pairs up corresponding elements from the two arrays
zip(BIG). # zip pairs up corresponding elements from the two arrays
find_all { |c| c[0] != 'zero' }.
map{ |c| c.join ' '}. # join ["forty", "thousand"]
map{ |c| c.join ' '}. # join ["forty", "thousand"]
reverse.
join(', '). # join chunks
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|
data = [-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,
987_654_321_098_765_432_109_876_543_210_987_654,
123890812938219038290489327894327894723897432]
data.each do |n|
print "#{n}: "
begin
puts "'#{wordify n}'"

View file

@ -1,10 +1,7 @@
package org.rosettacode
package numbernames
import scala.annotation.tailrec
import scala.collection.parallel.ParSeq
/** Spells a English numeral longhand. The numbers are expressed using words.
/** Spells an English numeral longhand. The numbers are expressed using words.
*
* The implementation goes up to 10<sup>69</sup>-1 and also supports negative and zero inputs.
*
@ -18,11 +15,11 @@ trait LongHand {
* @param showAnd flag the output extra and in output, default off
* @param zeroString the word for 0, default to "zero"
* @param showHyphen hyphenate all compound numbers e.g. twenty-four, default is on
* @return the numeric value in words
* @return the numeric value expressed in words
*/
def longhand(numeral: BigInt,
zeroString: String = "zero",
showAnd: Boolean = false,
zeroString: String = "zero",
showHyphen: Boolean = true): String = {
val condAndString = if (showAnd) "and " else ""
@ -37,11 +34,11 @@ trait LongHand {
val eval = (nnn.par.map(_.toString.toInt).reverse zip ParSeq('units, 'tens, 'hundreds)).reverse
eval.map {
case (d, 'units) if eval.seq.contains((1, 'tens)) => onesAndTeens(d + 10)
case (d, 'units) if eval.seq.contains(1, 'tens) => onesAndTeens(d + 10)
case (d, 'units) if (isLSDgroup && nnn == "0") => zeroString
case (d, 'units) => onesAndTeens(d)
case (d, 'hundreds) if d > 0 => onesAndTeens(d) + hundredString + condAndString
case (d, 'tens) if d > 1 && eval.seq.contains((0, 'units)) => tens(d)
case (d, 'tens) if d > 1 && eval.seq.contains(0, 'units) => tens(d)
case (d, 'tens) if d > 1 => tens(d) + condHyphenString //'
case _ => ""
}.mkString + strE3
@ -52,11 +49,8 @@ trait LongHand {
def compose(n: BigInt): String = {
// "1234" becomes List((1,"thousand"), (234, ""))
val decGroups = n.toString.reverse.grouped(3).map(_.reverse).toSeq.par // Group into powers of thousands
.zip(shortScale) // // Name the powers of Thousands
.reverse // // Put it back to most-significant first
if (decGroups.size < 24) // Detect overflow trap
{ // Send per group sections to composeScale
if (decGroups.size <= shortScale.size) // Detect overflow
{ // Send per group section to composeScale
@tailrec
def iter(elems: Seq[(String, String)], acc: String): String = {
elems match {
@ -65,28 +59,28 @@ trait LongHand {
}
case _ => acc
}
}
iter(decGroups.toList, "").mkString.trim
} // Group of decimals are accompanied with the short scale name.
iter(decGroups.zip(shortScale).reverse.toList, "").mkString.trim
} else "###.overflow.###"
} // def compose(
// Here starts def longhand(
if (numeral < 0) "minus " + compose(-numeral) else compose(numeral)
} // End def longhand( @ 91 lines
} // End def longhand(
val onesAndTeens = {
def lowNumerals = "one two three four five six seven eight nine ten eleven twelve".split(' ').map(_ + " ")
def tenties = "thir four fif six seven eigh nine".split(' ').map(_ + "teen ")
ParSeq("") ++ lowNumerals ++ tenties
private val onesAndTeens = {
def dozen = "one two three four five six seven eight nine ten eleven twelve".split(' ').map(_ + " ").par
def teens = "thir four fif six seven eigh nine".split(' ').map(_ + "teen ").par
ParSeq("") ++ dozen ++ teens
}
val tens = (Array[String]("", "") ++ ("twen thir for fif six seven eigh nine".split(' ')).
map(_ + "ty")).par
def hundredString = "hundred "
lazy val shortScale = {
private val tens = ParSeq("", "") ++
("twen thir for fif six seven eigh nine".split(' ')).map(_ + "ty")
private final val hundredString = "hundred "
private val shortScale = {
def p1 = "m b tr quadr quint sext sept oct non dec".split(' ').map(_ + "illion ").par
def p2 = "un duo tre quattuor quin sex septen octo novem ".split(' ').map(_ + "decillion ").par
def p3 = ("vigint cent".split(' ').map(_ + "illion ") :+ "overflow trap").par
def p3 = "vigint cent".split(' ').map(_ + "illion ").par
ParSeq("", "thousand ") ++ p1 ++ p2 ++ p3
}
} // trait LongHand