这是惯用的Clojure吗?

时间:2013-03-14 16:55:06

标签: clojure

我已经开始使用Clojure进行Project Euler,这是学习Clojure的第一步。我已经解决了第一个任务:

  

查找低于1000的3或5的所有倍数的总和。

我以前用Python解决过它:

sum(i for i in xrange(1000) if i%3==0 or i%5==0)

这是我的第一次Clojure尝试:

(reduce +
  (filter 
    (fn [x]
      (or 
        (= 0 (mod x 3)) 
        (= 0 (mod x 5))))
    (range 1000)))

我真的很惊讶它有多详细,但我很确定这是因为我的风格和对Clojure习语的无知。

这个Clojure代码的惯用版本会是什么样的?

3 个答案:

答案 0 :(得分:8)

我就这样做了:

(apply +
  (filter #(or (zero? (mod % 3))
               (zero? (mod % 5)))
    (range 1000)))

使我的解决方案稍微更具惯用性的原因是使用匿名函数阅读器宏#(...)zero? fn

您的解决方案不同,但同样良好

BTW - 解决欧拉问题是学习新语言的好方法 - 你无法从书本中获取所有内容。

修改

我决定提供一个更符合你的Python版本的不同解决方案(不是很漂亮的IMO)

(apply +
  (for [i (range 1000) :when (or (zero? (mod i 3))
                                 (zero? (mod i 5)))]
    i))

答案 1 :(得分:8)

只是另一个版本:

(defn sum-of [n]
  (reduce + (range n 1000 n)))

(+ (sum-of 3) (sum-of 5) (- (sum-of 15)))

答案 2 :(得分:0)

我喜欢尝试解决Project Euler的一般解决方案,所以这是我的通用解决方案:

(defn sum-multiples [nums lim]
  (reduce
   +
   (filter
    (fn [x]
      (some identity
            (map #(zero? (mod x %)) nums)))
    (range lim))))

然后只需致电:

(sum-multiples [3 5] 1000)