blob: 50b9488dda33685aa948e6fe318ee279cf6933c0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nlpcraft.common.nlp.numeric
import java.text.DecimalFormat
import org.apache.nlpcraft.common._
/**
* Converts numbers to their textual (word) presentation.
*/
object NCNumericGenerator {
private final val FORMATTER = new DecimalFormat("000000000000")
private final val TENS_NAMES = IndexedSeq(
"",
" ten",
" twenty",
" thirty",
" forty",
" fifty",
" sixty",
" seventy",
" eighty",
" ninety")
private final val NUM_NAMES = IndexedSeq(
"",
" one",
" two",
" three",
" four",
" five",
" six",
" seven",
" eight",
" nine",
" ten",
" eleven",
" twelve",
" thirteen",
" fourteen",
" fifteen",
" sixteen",
" seventeen",
" eighteen",
" nineteen"
)
// Less 1000.
private def convertSmall(n: Int): String = {
val (s, i) =
if (n % 100 < 20)
(NUM_NAMES(n % 100), n / 100)
else {
val s1 = NUM_NAMES(n % 10)
val i1 = n / 10
(TENS_NAMES(i1 % 10) + s1, i1 / 10)
}
if (i == 0) s else s"${NUM_NAMES(i)} hundred $s"
}
def toWords(n: Long): String = {
// 0 to 999 999 999 999
if (n == 0)
"zero"
else {
val sNum = FORMATTER.format(n)
val s10x9 = Integer.parseInt(sNum.substring(0, 3))
val s10x6 = Integer.parseInt(sNum.substring(3, 6))
val s10x3 = Integer.parseInt(sNum.substring(6, 9))
val s10x1 = Integer.parseInt(sNum.substring(9, 12))
val n10x9 = s10x9 match {
case 0 => ""
case _ => convertSmall(s10x9) + " billion "
}
val n10x6 = s10x6 match {
case 0 => ""
case _ => convertSmall(s10x6) + " million "
}
val n10x3 = s10x3 match {
case 0 => ""
case 1 => "one thousand "
case _ => convertSmall(s10x3) + " thousand "
}
val n10x1 = convertSmall(s10x1)
U.normalize(n10x9 + n10x6 + n10x3 + n10x1," ")
}
}
def generate(n: Int): Map[Int, String] = (1 to n).map(i => i -> toWords(i)).toMap
}