2015-07-11 32 views
1

試行此代碼段似乎並沒有被工作完全正確..瞭解復發

(defn- multiple_of? 
    [div num] 
    (= (mod num div) 0)) 

(defn sum_of_multiples_from 
    ([start] (sum_of_multiples_from start 0)) 
    ([start total] 
    (if (<= start 0) 
    total 
    (recur (dec start) (or (multiple_of? 3 start) (multiple_of? 5 start) 
          (+ total start) start))))) 

我收到以下錯誤:

java.lang.Boolean cannot be cast to java.lang.Number

我猜測它做與:

(recur (dec start) (or (multiple_of? 3 start) (multiple_of? 5 start) 
          (+ total start) 
          start))))) 

但我不知道爲什麼,我是clojure新手,所以我試圖得到一個復發的把握。

回答

3

or調用返回一個布爾((multiple_of? 3 start))儘快開始是3

在Clojure中的倍數,or總是返回參數一個 - 無論是第一truish一個如果存在的話,否則就是最後的一個錯誤。

+0

請問_clojure_方式是,如果包裝在一個?像'(如果(或多重?3開始)(multiple_of?5開始))(+總開始)開始)'或者我離開? – deano

+0

'(if(或multiple_of?3 start)...)'將測試函數'multiple_of?'而不調用它。你需要parens來打電話。 '(if(或(multiple_of?3 start)(multiple_of?5 start))...)' – noisesmith

4

你真的想要一個條件表達式爲你的recur,並且總是返回一個數字。例如:

(defn sum_of_multiples_from 
    ([start] (sum_of_multiples_from start 0)) 
    ([start total] 
    (if (<= start 0) 
     total 
     (recur (dec start) 
     (if (or (multiple_of? 3 start) (multiple_of? 5 start)) 
      (+ total start) 
      total))))) 

請注意,這是一種用函數式語言實現此功能的奇怪方式。你真的從一系列採摘值和增加他們,所以它是更好地實現這個作爲一個過濾器和一個降低,例如:

(reduce + (filter #(or (multiple_of? 3 %) (multiple_of? 5 %)) (range 50))) 
=> 543 
+0

我最終做了類似於你的改進解決方案。我使用apply來代替reduce。 – deano