2013-03-14 11 views
7

私は、Clojureを学ぶ最初のスタブとして、Clojureを使ってProject Eulerを始めました。この慣用のClojureですか?

は、私が以前にPythonでそれを解決してきた1000

以下の3または5の全ての倍数の和を探す::私は、最初の割り当てを解決してきました

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

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

私は実際にそれを得た方法、詳細については驚いていますが、私:これが私の最初のClojureの試みでありますそれは私のスタイルとClojureイディオムの無知のためだと確信しています。

このClojureコードの慣用バージョンはどのように見えますか?

答えて

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

おかげで多くのことを、! apply vs reduceを使用する利点は何でしょうか? – gumuz

+1

'+'は変数arityを持っているので、 '+'を何度も実行することができません。実際には、argリストが2を超えると '+'は 'reduce'を使います(' + 'のソースを参照)ので、' reduce'を使うのと同じです。この例では、それは本当に自分のスタイルだけです。 – Kyle

+0

もう一度お返事ありがとうございます。例えば、あなたがor引数を整列させた方法を主張するスタイルガイドがありますか? – gumuz

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)(範囲5 1000 5))))' – ToBeReplaced

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) 
関連する問題