Numbers
Data Types
Interview Questions
(ns number-to-words (:require [clojure.string :refer [join]])) (def digit-to-word {1 "One" 2 "Two" 3 "Three" 4 "Four" 5 "Five" 6 "Six" 7 "Seven" 8 "Eight" 9 "Nine"}) (def tens-to-word { 20 "Twenty" 30 "Thirty" 40 "Fourty" 50 "Fifty" 60 "Sixty" 70 "Seventy" 80 "Eighty" 90 "Ninety"}) (def teen-to-word {10 "Ten" 11 "Eleven" 12 "Twelve" 13 "Thirteen" 14 "Fourteen" 15 "Fifteen" 16 "Sixteen" 17 "Seventeen" 18 "Eighteen" 19 "Nineteen"}) (defn divmod [n d] [(quot n d) (mod n d)]) (defn tens [n & {:keys [zero] :or {zero ""}}] (let [[tens ones] (divmod n 10) digit (digit-to-word ones)] (condp = tens 0 (or digit zero) 1 (teen-to-word n) (str (tens-to-word (* 10 tens)) (when digit (str "-" digit)))))) (defn order [d name f n] (let [[hs ts] (divmod n d)] (str "" (when (> hs 0) (str (f hs) " " name)) (when (> ts 0) (str (when (> hs 0) " ") (f ts)))))) (def hundreds (partial order 100 "Hundred" tens)) (def orders ["" " Thousand" " Million" " Billion" " Trillion"]) (defn addp [lst n o] (if (> n 0) (conj lst (str (hundreds n) (orders o))) lst)) (defn convert- [x] (join ", " (loop [i 0, n x, out '()] (let [[a b] (divmod n 1000)] (cond (>= a 1000) (recur (inc i) a (addp out b i)) (> a 0) (-> out (addp b i) (addp a (inc i))) :else (addp out b i) ))))) (defn convert [x] (case (compare x 0) -1 (str "Negative " (convert- (- (int x)))) 0 "Zero" 1 (convert- (int x)) nil))
- (ns number-to-words
- (:require [clojure.string :refer [join]]))
- (def digit-to-word
{1 "One"2 "Two"3 "Three"4 "Four"5 "Five"6 "Six"7 "Seven"8 "Eight"- {1 "One" 2 "Two" 3 "Three" 4 "Four"
- 5 "Five" 6 "Six" 7 "Seven" 8 "Eight"
- 9 "Nine"})
- (def tens-to-word
- {
20 "Twenty"30 "Thirty"40 "Fourty"50 "Fifty"60 "Sixty"70 "Seventy"80 "Eighty"90 "Ninety"})- 20 "Twenty" 30 "Thirty" 40 "Fourty"
- 50 "Fifty" 60 "Sixty" 70 "Seventy"
- 80 "Eighty" 90 "Ninety"})
- (def teen-to-word
{10 "Ten"11 "Eleven"12 "Twelve"13 "Thirteen"14 "Fourteen"15 "Fifteen"16 "Sixteen"17 "Seventeen"18 "Eighteen"- {10 "Ten" 11 "Eleven" 12 "Twelve"
- 13 "Thirteen" 14 "Fourteen" 15 "Fifteen"
- 16 "Sixteen" 17 "Seventeen" 18 "Eighteen"
- 19 "Nineteen"})
(defn- small-number-to-words[x](cond(<= x 9) (digit-to-word x)(< x 20) (teen-to-word x)(< x 100)(let [ones-part (mod x 10)tens-part (- x ones-part)](str (tens-to-word tens-part) "-"(digit-to-word ones-part)))(<= x 999)(let [small-part (mod x 100)hundreds-digit (-> x (- small-part) (/ 100))](str (digit-to-word hundreds-digit) " Hundred " (small-number-to-words small-part)))))(defn- digit-shift[x shift](-> x (- (mod x shift)) (/ shift) int))(defn convert[x](loop [words [] x x](cond(-> x (>= 1e6))(recur (conj words "One Million")(- x 1e6))(-> x (>= 1e3))(recur (conj words(str(-> x (digit-shift 1000) small-number-to-words)" Thousand"))(mod x 1000))(-> x (> 0))(recur (conj words (small-number-to-words x)) 0):else (join ", " words))))- (defn divmod [n d] [(quot n d) (mod n d)])
- (defn tens [n & {:keys [zero] :or {zero ""}}]
- (let [[tens ones] (divmod n 10)
- digit (digit-to-word ones)]
- (condp = tens
- 0 (or digit zero)
- 1 (teen-to-word n)
- (str (tens-to-word (* 10 tens)) (when digit (str "-" digit))))))
- (defn order [d name f n]
- (let [[hs ts] (divmod n d)]
- (str ""
- (when (> hs 0) (str (f hs) " " name))
- (when (> ts 0) (str (when (> hs 0) " ") (f ts))))))
- (def hundreds (partial order 100 "Hundred" tens))
- (def orders ["" " Thousand" " Million" " Billion" " Trillion"])
- (defn addp [lst n o]
- (if (> n 0) (conj lst (str (hundreds n) (orders o))) lst))
- (defn convert- [x]
- (join ", "
- (loop [i 0, n x, out '()]
- (let [[a b] (divmod n 1000)]
- (cond
- (>= a 1000) (recur (inc i) a (addp out b i))
- (> a 0) (-> out (addp b i) (addp a (inc i)))
- :else (addp out b i)
- )))))
- (defn convert [x]
- (case (compare x 0)
- -1 (str "Negative " (convert- (- (int x))))
- 0 "Zero"
- 1 (convert- (int x))
- nil))
(ns number-to-word-test (:require [clojure.test :refer :all] [number-to-words])) (deftest conversion-test (is (= "Zero" (number-to-words/convert 0))) (is (= "One" (number-to-words/convert 1))) (is (= "Seven" (number-to-words/convert 7))) (is (= "Eleven" (number-to-words/convert 11))) (is (= "Ninety" (number-to-words/convert 90))) (is (= "Twenty-Six" (number-to-words/convert 26))) (is (= "Three Hundred Eleven" (number-to-words/convert 311))) (is (= "Two Hundred Two" (number-to-words/convert 202))) (is (= "Seven Hundred" (number-to-words/convert 700))) (is (= "Five Hundred Ninety-Nine" (number-to-words/convert 599))) (is (= "One Million" (number-to-words/convert 1e6))) (is (= "Nine Hundred Ninety-Nine Thousand" (number-to-words/convert 999e3)) (is (= "Six Hundred Twelve Thousand, Three Hundred Twenty-Three" (number-to-words/convert 612323)))))
- (ns number-to-word-test
- (:require [clojure.test :refer :all]
- [number-to-words]))
- (deftest conversion-test
- (is (= "Zero" (number-to-words/convert 0)))
- (is (= "One" (number-to-words/convert 1)))
- (is (= "Seven" (number-to-words/convert 7)))
- (is (= "Eleven" (number-to-words/convert 11)))
- (is (= "Ninety" (number-to-words/convert 90)))
- (is (= "Twenty-Six" (number-to-words/convert 26)))
- (is (= "Three Hundred Eleven" (number-to-words/convert 311)))
- (is (= "Two Hundred Two" (number-to-words/convert 202)))
- (is (= "Seven Hundred" (number-to-words/convert 700)))
- (is (= "Five Hundred Ninety-Nine" (number-to-words/convert 599)))
- (is (= "One Million" (number-to-words/convert 1e6)))
- (is (= "Nine Hundred Ninety-Nine Thousand" (number-to-words/convert 999e3))
- (is (= "Six Hundred Twelve Thousand, Three Hundred Twenty-Three" (number-to-words/convert 612323)))))