Skip to content

Instantly share code, notes, and snippets.

@pragyanatvade
Created February 18, 2022 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pragyanatvade/81aa1d3992e4ff0a1b86216070a8c522 to your computer and use it in GitHub Desktop.
Save pragyanatvade/81aa1d3992e4ff0a1b86216070a8c522 to your computer and use it in GitHub Desktop.
Clojure library to convert number to words
(ns number-to-words
(:require [clojure.string :as cstr]))
(def ^:private log10 #(java.lang.Math/log10 %))
(def ^:private char->int #(Character/getNumericValue %))
(def ^:private number-map
{0 ""
1 "one"
2 "two"
3 "three"
4 "four"
5 "five"
6 "six"
7 "seven"
8 "eight"
9 "nine"
10 "ten"
11 "eleven"
12 "twelve"
13 "thirteen"
14 "fourteen"
15 "fifteen"
16 "sixteen"
17 "seventeen"
18 "eighteen"
19 "nineteen"
20 "twenty"
30 "thirty"
40 "forty"
50 "fifty"
60 "sixty"
70 "seventy"
80 "eighty"
90 "ninety"})
#_(log10 0)
(defn number->word
"Takes a number and return a full written string form."
[number]
(if (zero? number)
"zero"
(let [digit-count (int (log10 number))
divisible? (fn [number divider] (zero? (rem number divider)))
number-digits (fn [number n] (char->int (.charAt (str number) n)))]
(cond
;; handle million part
(>= digit-count 6) (if (divisible? number 1000000)
(cstr/join " " [(number->word (int (/ number 1000000)))
"million"])
(cstr/join " " [(number->word (int (/ number 1000000)))
"million"
(number->word (rem number 1000000))]))
;; handle thousand part
(>= digit-count 3) (if (divisible? number 1000)
(cstr/join " " [(number->word (int (/ number 1000)))
"thousand"])
(cstr/join " " [(number->word (int (/ number 1000)))
"thousand"
"and"
(number->word (rem number 1000))]))
;; handle hundred part
(>= digit-count 2) (if (divisible? number 100)
(cstr/join " " [(number-map (int (/ number 100)))
"hundred"])
(cstr/join " " [(number-map (int (/ number 100)))
"hundred"
"and"
(number->word (rem number 100))]))
;; handle the last two digits
(< number 20) (number-map number)
(divisible? number 10) (number-map number)
:else (cstr/join " " [(number-map (* 10 (number-digits number 0)))
(number-map (number-digits number 1))])))))
(number->word 0)
;; => "zero"
(number->word 9)
;; => "nine"
(number->word 99)
;; => "ninety-nine"
(number->word 999)
;; => "nine hundred and ninety-nine"
(number->word 9999)
;; => "nine thousand nine hundred and ninety-nine"
(number->word 99999)
;; => "ninety-nine thousand nine hundred and ninety-nine"
(number->word 999999)
;; => "nine hundred and ninety-nine thousand nine hundred and ninety-nine"
(number->word 9999999)
;; => "nine million nine hundred and ninety-nine thousand nine hundred and ninety-nine"
(number->word 99999999)
;; => "ninety-nine million nine hundred and ninety-nine thousand nine hundred and ninety-nine"
(number->word 999999999)
;; => "nine hundred and ninety-nine million nine hundred and ninety-nine thousand nine hundred and ninety-nine"
(number->word 9999999999)
;; => "nine thousand nine hundred and ninety-nine million nine hundred and ninety-nine thousand nine hundred and ninety-nine"
(number->word 1)
;; => "one"
(number->word 22)
;; => "twenty two"
(number->word 109)
;; => "one hundred and nine"
(number->word 123)
;; => "one hundred and twenty three"
(number->word 170)
;; => "one hundred and seventy"
(number->word 998)
;; => "nine hundred and ninety eight"
(number->word 1001)
;; => "one thousand one"
(number->word 1502)
;; => "one thousand five hundred and two"
(number->word 837583)
;; => "eight hundred and thirty seven thousand five hundred and eighty three"
(number->word 93798647)
;; => "ninety-three million seven hundred and ninety-eight thousand six hundred and forty-seven"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment