RosettaCodeData/Task/Four-is-magic/Clojure/four-is-magic.clj

50 lines
1.9 KiB
Clojure

(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*))