7

我已经开始使用 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 代码的惯用版本会是什么样子?

4

3 回答 3

9

我是这样做的:

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

使我的解决方案更加惯用的原因是使用匿名函数阅读器宏,#(...)以及zero? fn

您的解决方案不同但同样

顺便说一句 - 解决欧拉问题是学习一门新语言的好方法 - 你不能从一本书中得到所有东西。

编辑:

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

(apply +
  (for [i (range 1000) :when (or (zero? (mod i 3))
                                 (zero? (mod i 5)))]
    i))
于 2013-03-14T16:58:13.980 回答
9

只是另一个版本:

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

(+ (sum-of 3) (sum-of 5) (- (sum-of 15)))
于 2013-03-14T17:05:43.197 回答
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)
于 2013-03-15T21:46:14.193 回答