罗马数字kata在clojure

时间:2014-07-10 04:52:46

标签: clojure

我正在学习clojure,我写了这段代码来解决罗马数字kata:

(def romans (sorted-map-by >
             1000 "M"
             500 "D"
             400 "CD"
             100 "C"
             90 "XC"
             50 "L"
             40 "XL"
             10 "X"
             9 "IX"
             5 "V"
             4 "IV"
             1 "I"))

(defn roman-digit [arabic]
  (first (filter (fn [[key value]]
          (>= arabic key)) romans)))

(defn arabic-to-roman [arabic]
  (def roman (roman-digit arabic))
  (if (> arabic 0)
    (apply str (val roman) (arabic-to-roman (- arabic (key roman))))
    ""))

我想知道如何让这段代码更有效/惯用/干净。我确信我可以学到很多新东西。

感谢。

1 个答案:

答案 0 :(得分:2)

这是我的捅。

(defn roman-digit [arabic]
  (first
    (filter #(>= arabic (first %))
      [[1000 "M" ]
       [500  "D" ]
       [400  "CD"]
       [100  "C" ]
       [90   "XC"]
       [50   "L" ]
       [40   "XL"]
       [10   "X" ]
       [9    "IX"]
       [5    "V" ]
       [4    "IV"]
       [1    "I" ]])))

(defn arabic-to-roman [arabic]
  (when (> arabic 0)
    (let [[arabic-diff roman] (roman-digit arabic)]
      (apply str roman (arabic-to-roman (- arabic arabic-diff))))))

这里发生了什么?

  • 当你有一组最终用作序列的有序闭合值时,使用正确顺序的对向量需要更少的仪式。
  • 永远不要在这样的条件下def。将def视为全局变量(符号)的声明和定义。对于本地范围(绑定),请使用let
  • 首选when优先于if,特别是如果只有一个分支。请注意,strapply都为nil做了正确的事情(当arabic为0时,它会在递归的底部返回。)