Ad
Numbers
Data Types
Interview Questions
Code
Diff
  • (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))