105 lines
3.4 KiB
Clojure
105 lines
3.4 KiB
Clojure
(ns auto-ap.numeric
|
|
(:require [clojure.string :as str]))
|
|
|
|
(def ^:private smalls ["zero"
|
|
"one"
|
|
"two"
|
|
"three"
|
|
"four"
|
|
"five"
|
|
"six"
|
|
"seven"
|
|
"eight"
|
|
"nine"
|
|
"ten"
|
|
"eleven"
|
|
"twelve"
|
|
"thirteen"
|
|
"fourteen"
|
|
"fifteen"
|
|
"sixteen"
|
|
"seventeen"
|
|
"eighteen"
|
|
"nineteen"])
|
|
|
|
(def ^:private tens ["twenty"
|
|
"thirty"
|
|
"forty"
|
|
"fifty"
|
|
"sixty"
|
|
"seventy"
|
|
"eighty"
|
|
"ninety"])
|
|
|
|
(def ^:private magnitudes ["thousand"
|
|
"million"
|
|
"billion"
|
|
"trillion"
|
|
"quadrillion"
|
|
"quintillion"
|
|
"sextillion"
|
|
"septillion"
|
|
"octillion"
|
|
"nonillion"
|
|
"decillion"
|
|
"undecillion"
|
|
"duodecillion"
|
|
"tredecillion"
|
|
"quattuordecillion"
|
|
"quindecillion"
|
|
"quinquadecillion"
|
|
"sexdecillion"
|
|
"sedecillion"
|
|
"septendecillion"
|
|
"octodecillion"
|
|
"novemdecillion"
|
|
"novendecillion"
|
|
"vigintillion"
|
|
#_"centillion"])
|
|
|
|
(defn words
|
|
[n]
|
|
{:pre [(not (neg? n))]}
|
|
(cond
|
|
(< n 20) (smalls n)
|
|
(< n 100) (let [pre (tens (- (quot n 10) 2)),
|
|
x (rem n 10)]
|
|
(if (zero? x) pre (str pre "-" (words x))))
|
|
(< n 1000) (let [hun (quot n 100),
|
|
x (rem n 100),
|
|
s (str (words hun) " hundred")]
|
|
(if (zero? x) s (str s " and " (words x))))
|
|
:else (loop [parts [] n n mag -1]
|
|
(if (zero? n)
|
|
(str/join " " parts)
|
|
(let [x (rem n 1000)
|
|
n (quot n 1000)
|
|
parts (if (zero? x)
|
|
parts
|
|
(let [s (words x)]
|
|
(cons
|
|
(if (neg? mag)
|
|
(if (< x 100)
|
|
(str "and " s)
|
|
s)
|
|
(str s " " (magnitudes mag)))
|
|
parts)))]
|
|
(recur parts n (inc mag)))))))
|
|
|
|
|
|
(defn num->words [num]
|
|
(let [total-cents (int (* 100 num))
|
|
dollar-num (int (quot total-cents 100))
|
|
cent-num (int (rem total-cents 100))
|
|
dollars (str (words dollar-num) " dollars")
|
|
cents (str (words cent-num) " cents")]
|
|
(cond
|
|
(and (> dollar-num 0) (> cent-num 0))
|
|
(str dollars " and " cents)
|
|
|
|
(> dollar-num 0)
|
|
dollars
|
|
|
|
:else
|
|
cents)))
|