这是惯用的Clojure吗?
我已经开始使用Clojure做Euler项目,作为学习Clojure的第一步。我已经解决了第一个任务: 求1000以下所有3或5的倍数之和 我以前用Python解决过这个问题:这是惯用的Clojure吗?,clojure,Clojure,我已经开始使用Clojure做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))))
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代码的惯用版本会是什么样子?我就是这样做的:
(apply +
(filter #(or (zero? (mod % 3))
(zero? (mod % 5)))
(range 1000)))
使我的解决方案更为惯用的是使用匿名函数读取器宏、#(…)
和zero?
fn
您的解决方案不同,但同样好
顺便说一句-解决欧拉问题是学习一门新语言的好方法-你不可能从一本书中得到所有东西
编辑:
我决定提供一个与您的Python版本更加内联的不同解决方案(在IMO中不是很好)
只是另一个版本:
(defn sum-of [n]
(reduce + (range n 1000 n)))
(+ (sum-of 3) (sum-of 5) (- (sum-of 15)))
我喜欢尝试为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)
非常感谢,这会让它干净很多!这里使用apply vs reduce有什么好处?
+
具有可变的arity,因此它阻止我们多次执行+
。实际上,它相当于使用reduce
,因为一旦arg列表超过2,+
就会使用reduce
(参见+
的源代码)。在这个例子中,这实际上只是我的风格,而不是其他任何东西。不幸的是,我仍然在学习“正确”的风格-这是一本很好的读物-你会注意到我并没有真正遵循它100%@gumuz我添加了一个更符合你的Python解决方案的版本-在我看来没有那么干净。主题的变化:(apply+(对于[I(范围1000)]:什么时候(一些零?(映射(部分模i)[3 5])]i))
Cute。另外(减少+(不同的(concat(范围3 1000 3)(范围5 1000 5)))
(sum-multiples [3 5] 1000)