(require '[clojure.edn:as edn])
(def names { 0 "zero"      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"      100 "hundred"

            1000          "thousand"     1000000          "million"      1000000000 "billion"
            1000000000000 "trillion"     1000000000000000 "quadrillion"
            1000000000000000000          "quintillion" })

(def powers-of-10 (reverse (sort (filter #(clojure.string/ends-with? (str %) "00") (keys names)))))

(defn name-of [n]
  (let [p (first (filter #(>= n %) powers-of-10))]
    (cond
      (not (nil? p))
        (let [quotient  (quot n p)
              remainder (rem  n p)]
              (str (name-of quotient) " " (names p) (if (> remainder 0) (str " " (name-of remainder)))))

      (and (nil? p) (> n 20))
        (let [remainder  (rem n 10)
              tens       (- n remainder)]
              (str (names tens) (if (> remainder 0) (str " " (name-of remainder)))))

      true
        (names n))))

(defn four-is-magic
  ([n] (four-is-magic n ""))
  ([n prefix]
   (let [name ((if (empty? prefix) clojure.string/capitalize identity) (name-of n))
         new-prefix (str prefix (if (not (empty? prefix)) ", "))]
   (if (= n 4)
    (str new-prefix name " is magic.")
    (let [len (count name)]
      (four-is-magic len (str new-prefix name " is " (name-of len))))))))

(defn report [n]
  (println (str n ": " (four-is-magic n))))

(defn -main [& args]
  (doall (map (comp report edn/read-string) args)))


(if (not= "repl" *command-line-args*)
  (apply -main *command-line-args*))