Skip to content

Instantly share code, notes, and snippets.

@Slakah
Created July 3, 2020 16:04
Show Gist options
  • Save Slakah/44f71f29a5ef12e10d86bdfe8055ac80 to your computer and use it in GitHub Desktop.
Save Slakah/44f71f29a5ef12e10d86bdfe8055ac80 to your computer and use it in GitHub Desktop.
Scala ammonite script to turn a number into a a human readable(ish) representation, try ./num2word.sc 10002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
#!/usr/bin/env amm
@main
def main(n: BigInt): Unit =
println(num2wordList(n, List.empty).mkString(" "))
// https://en.wikipedia.org/wiki/Names_of_large_numbers
private val prefix2factor = List(
"Centillion" -> 303,
"Googol" -> 100,
"Vigintillion" -> 63,
"Novemdecillion" -> 60,
"Octodecillion" -> 57,
"Septendecillion" -> 54,
"Sexdecillion" -> 51,
"Quindecillion" -> 48,
"Quattuordecillion" -> 45,
"Tredecillion" -> 42,
"Duodecillion" -> 39,
"Undecillion" -> 36,
"Decillion" -> 33,
"Nonillion" -> 30,
"Octillion" -> 27,
"Septillion" -> 24,
"Sextillion" -> 21,
"Quintillion" -> 18,
"Quadrillion" -> 15,
"Trillion" -> 12,
"Billion" -> 9,
"Million" -> 6,
"Thousand" -> 3,
"Hundred" -> 2
).map { case (prefix, base10) => prefix -> BigInt(10).pow(base10) }
private def num2wordList(n: BigInt, acc: List[String]): List[String] = {
val found = prefix2factor.find { case (_, factor) => n >= factor }
found match {
case None =>
if (n < 10L) singleDigit2word(n.toLong) :: acc
else doubleDigit2wordList(n.toLong) ::: acc
case Some((prefix, factor)) =>
if (n % factor == 0) num2wordList(n / factor, prefix :: acc)
else num2wordList(n / factor, prefix :: num2wordList(n % factor, List.empty) ::: acc)
}
}
private def doubleDigit2wordList(n: Long): List[String] = {
assert(n >= 10L && n < 100L)
n match {
case 10 => List("Ten")
case 11 => List("Eleven")
case 12 => List("Twelve")
case 13 => List("Thirteen")
case 14 => List("Fourteen")
case 15 => List("Fifteen")
case 16 => List("Sixteen")
case 17 => List("Seventeen")
case 18 => List("Eighteen")
case 19 => List("Nineteen")
case 20 => List("Twenty")
case 30 => List("Thirty")
case 40 => List("Forty")
case 50 => List("Fifty")
case 60 => List("Sixty")
case 70 => List("Seventy")
case 80 => List("Eighty")
case 90 => List("Ninety")
case _ => doubleDigit2wordList((n / 10) * 10) :+ singleDigit2word(n % 10)
}
}
private def singleDigit2word(n: Long): String = {
assert(n < 10L)
n match {
case 0 => "Zero"
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
case 4 => "Four"
case 5 => "Five"
case 6 => "Six"
case 7 => "Seven"
case 8 => "Eight"
case 9 => "Nine"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment