2013-03-14 35 views
7

我已經開始使用Clojure進行Project Euler,作爲第一次嘗試學習Clojure。我已經解決了第一個任務:這是慣用的Clojure嗎?

找到3所有倍數低於1000

總和或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代碼的慣用版本是什麼樣的?

回答

8

這是我做的:

(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)) 
+0

非常感謝,這清除它頗有幾分!使用apply vs reduce會有什麼好處? – gumuz 2013-03-14 17:05:21

+1

'+'具有可變參數,因此它阻止我們多次執行'+'。實際上,這相當於使用'reduce',因爲'+'在arg列表超過2時使用'reduce'(請參閱'+'的源代碼)。在這個例子中,這實際上只是我的風格而已。 – Kyle 2013-03-14 17:07:15

+0

再次感謝,是否有一些風格指南,例如,提倡您對齊或參數的方式? – gumuz 2013-03-14 17:11:16

8

只是另一個版本:

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

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

可愛。同樣'(reduce +(distinct(concat(range 3 1000 3)(range 5 1000 5))))' – ToBeReplaced 2013-03-14 23:19:31

0

我像試圖解決項目歐拉的一般解決方案,所以這裏是我的通用解決方案:

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

,然後只要致電:

(sum-multiples [3 5] 1000) 
相關問題