74 lines
1.9 KiB
Nim
74 lines
1.9 KiB
Nim
import strutils, algorithm
|
|
|
|
const
|
|
tens = ["", "", "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"]
|
|
huge = ["", "", "million", "billion", "trillion", "quadrillion",
|
|
"quintillion", "sextillion", "septillion", "octillion", "nonillion",
|
|
"decillion"]
|
|
|
|
proc spellInteger(n: int64): string
|
|
|
|
proc nonzero(c: string, n: int, connect=""): string =
|
|
if n == 0: "" else: connect & c & spellInteger(n)
|
|
|
|
proc lastAnd(num): string =
|
|
var num = num
|
|
if "," in num:
|
|
let pos = num.rfind(",")
|
|
var (pre, last) =
|
|
if pos >= 0: (num[0 .. pos-1], num[pos+1 .. num.high])
|
|
else: ("", num)
|
|
if " and " notin last:
|
|
last = " and" & last
|
|
num = [pre, ",", last].join()
|
|
return num
|
|
|
|
proc big(e, n): string =
|
|
if e == 0:
|
|
spellInteger(n)
|
|
elif e == 1:
|
|
spellInteger(n) & " thousand"
|
|
else:
|
|
spellInteger(n) & " " & huge[e]
|
|
|
|
iterator base1000Rev(n): int =
|
|
var n = n
|
|
while n != 0:
|
|
let r = n mod 1000
|
|
n = n div 1000
|
|
yield r
|
|
|
|
proc spellInteger(n: int64): string =
|
|
if n < 0:
|
|
"minus " & spellInteger(-n)
|
|
elif n < 20:
|
|
small[int(n)]
|
|
elif n < 100:
|
|
let a = n div 10
|
|
let b = n mod 10
|
|
tens[int(a)] & nonzero("-", b)
|
|
elif n < 1000:
|
|
let a = n div 100
|
|
let b = n mod 100
|
|
small[int(a)] & " hundred" & nonzero(" ", b, " and")
|
|
else:
|
|
var sq = newSeq[string]()
|
|
var e = 0
|
|
for x in base1000Rev(n):
|
|
if x > 0:
|
|
sq.add big(e, x)
|
|
inc e
|
|
reverse sq
|
|
lastAnd(sq.join(", "))
|
|
|
|
for n in [0, -3, 5, -7, 11, -13, 17, -19, 23, -29]:
|
|
echo align($n, 4)," -> ",spellInteger(n)
|
|
|
|
var n = 201021002001
|
|
while n != 0:
|
|
echo align($n, 14)," -> ",spellInteger(n)
|
|
n = n div -10
|