Time for an 2014 update…

This commit is contained in:
Ingy döt Net 2014-01-17 05:32:22 +00:00
parent 372c577f83
commit 09687c4926
2520 changed files with 34227 additions and 7318 deletions

View file

@ -1,51 +1,35 @@
package org.rosettacode
package numbernames
import annotation.tailrec
import collection.parallel.ParSeq
import scala.annotation.tailrec
import scala.collection.parallel.ParSeq
/** Spells a number longhand
/** Spells a 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.
*
* @example longhand( 1234 ) // results in: "one thousand two hundred thirty-four".
*/
object SpellNumber extends App {
trait LongHand {
/** Spells a number longhand
*
* The solution is recursive by the triplets of decimal numbers.
* @param v the numeric value to be converted
* Done by recursively process the triplets of decimal numbers.
* @param numeral the numeric value to be converted
* @param showAnd flag the output extra and in output, default off
* @param zeroString the word for 0, default to "zero"
* @param showHyphen shows the hyphen e.g. twenty-four, default is on
* @param showHyphen hyphenate all compound numbers e.g. twenty-four, default is on
* @return the numeric value in words
*/
def longhand(v: BigInt,
def longhand(numeral: BigInt,
zeroString: String = "zero",
showAnd: Boolean = false,
showHyphen: Boolean = true): String = {
val onesAndTeens = {
val a1 = "one two three four five six seven eight nine ten eleven twelve".split(' ').map(_ + " ")
val a2 = "thir four fif six seven eigh nine".split(' ').map(_ + "teen ")
(Array[String]("") ++ a1 ++ a2).par
}
val tens = (Array[String]("", "") ++ ("twen thir for fif six seven eigh nine".split(' ')).
map(_ + "ty")).par
val hundredString = "hundred "
val condAndString = if (showAnd) "and " else ""
val condHyphenString = if (showHyphen) "-" else " "
val powersOfThousands = {
val p1 = "m b tr quadr quint sext sept oct non dec".split(' ').map(_ + "illion ").par
val p2 = "un duo tre quattuor quin sex septen octo novem ".split(' ').map(_ + "decillion ").par
val p3 = "vigint cent".split(' ').map(_ + "illion ") ++ Array("overflow trap").par
(Array("", "thousand ") ++ p1 ++ p2 ++ p3).par
}
// 234 becomes "two hundred [and] thirty-four"
def tripletGroup(nnn: String, isLSDgroup: Boolean, strE3: String): String = {
// 234 Becomes "two hundred [and] thirty-four"
def composeScale(nnn: String, isLSDgroup: Boolean, strE3: String): String = {
nnn match { // Rare exceptions confirms the rule
case "000" => ""
case "100" => onesAndTeens(1) + hundredString + strE3 // Solves the faulty hundred AND thousand problem
@ -63,13 +47,13 @@ object SpellNumber extends App {
}.mkString + strE3
}
}
} // def tripletGroup(
} // def composeScale(
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(powersOfThousands) // // Name the powers of Thousands
.reverse // // Put it back to most-significant first
.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
@ -77,7 +61,7 @@ object SpellNumber extends App {
def iter(elems: Seq[(String, String)], acc: String): String = {
elems match {
case (group, powers) :: tail => {
iter(tail, acc + tripletGroup(group, tail == Nil, powers))
iter(tail, acc + composeScale(group, tail == Nil, powers))
}
case _ => acc
}
@ -87,9 +71,27 @@ object SpellNumber extends App {
} // def compose(
// Here starts def longhand(
if (v < 0) "minus " + compose(-v) else compose(v)
if (numeral < 0) "minus " + compose(-numeral) else compose(numeral)
} // End def longhand( @ 91 lines
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
}
val tens = (Array[String]("", "") ++ ("twen thir for fif six seven eigh nine".split(' ')).
map(_ + "ty")).par
def hundredString = "hundred "
lazy 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
ParSeq("", "thousand ") ++ p1 ++ p2 ++ p3
}
} // trait LongHand
object SpellNumber extends LongHand with App {
// Main entry A little test...
{ // Anonymous ordered list as test set
def testVal1 = BigInt("1" * 69)
@ -105,6 +107,6 @@ object SpellNumber extends App {
ParSeq(-Long.MaxValue, -1000000000, 12, 13, 19, 20, 21, 112, 1001, 1012, 1013,
Long.MaxValue - 1, Long.MaxValue - 13, testVal1, testVal9)) ++
(for (z <- 0 to 69) yield BigInt(10).pow(z)) // powers of ten
}.seq.sorted.
foreach(num => println(f"""$num%+,80d -> ${longhand(v = num, showAnd = true)}"""))
} // object SpellNumber
}.seq.sorted.foreach(num => println(f"$num%+,80d -> ${longhand(numeral = num, showAnd = true)}"))
} // object SpellNumber @ line 110