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"~~~~5 "Five"~~- {1 "One" 2 "Two" 3 "Three" 4 "Four"
- 5 "Five" 6 "Six" 7 "Seven" 8 "Eight"
- 9 "Nine"})
- (def tens-to-word
- {
~~20 "Twenty"~~~~50 "Fifty"~~~~80 "Eighty"~~- 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"~~~~16 "Sixteen"~~- {10 "Ten"
- 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)****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) in**t))~~(defn convert~~~~(~~**loop [words [] x x]**~~(~~**cond****(-> x (>= 1e6))****(recur (conj words "One Million")****(- x 1e6))****-> x (>= 1e3))****conj words****(str****x (digit-shift 1000) small-number-to-words)****" Thousand"))****(mod x 1000))****(-> x (> 0))****(recur**(con**j 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**-to-word**ones)]** -
**condp = tens** **0 (or digit zero**)-
**1 (teen-to-word n)** -
**(* 10**tens**)) (when digit (str**"-"**digit))))))** -
**(defn order [d name f n]****[hs ts] (div**mod**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))) ls**t)) - (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 "**(con**vert- (- (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)))))