Skip to content

Instantly share code, notes, and snippets.

@aquach
Created October 16, 2014 22:15
Show Gist options
  • Save aquach/7fa20d5925a03d39a612 to your computer and use it in GitHub Desktop.
Save aquach/7fa20d5925a03d39a612 to your computer and use it in GitHub Desktop.
Numbers to English words
object NumberUtils {
private def numberUnderThousandToEnglish(number: Int) = {
val hundreds = number / 100
val tensAndOnes = number % 100
val tens = tensAndOnes / 10
val ones = number % 10
val hundredsStr = if (hundreds > 0) Some(numNames(hundreds) + " hundred") else None
val restStr = numNames.get(tensAndOnes).map(s => List(Some(s))).getOrElse(
List(
if (tens > 0) Some(tensNames(tens)) else None,
if (ones > 0) Some(numNames(ones)) else None
)
)
(hundredsStr :: restStr).flatten.mkString(" ")
}
def numberToEnglish(number: Int): String = {
if (number == 0) return "zero"
val isPositive = number > 0
val absNumber = math.abs(number)
// 23456 -> List(456, 23). We group starting from the right rather than from the left.
val magnitudeChunks = absNumber.toString.reverse.grouped(3).toList.map(_.reverse.toInt)
val magnitudeStrings = magnitudeChunks.zip(None :: magnitudesByThree.map(Some(_))).filter(_._1 > 0).map {
case (quantity, magStr) => List(Some(numberUnderThousandToEnglish(quantity)), magStr).flatten.mkString(" ")
}
(if (isPositive) "" else "minus ") + magnitudeStrings.reverse.mkString(" ")
}
private val tensNames = (1 to 9).zip(List("ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety")).toMap
private val numNames =
(1 to 19).zip(List("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen")).toMap
private val magnitudesByThree = List(
"thousand",
"million",
"billion"
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment