我开始从头开始学习Clojure并且我坚持我的功能。我试图找到低于1000的3或5的所有倍数的总和。这就是我所做的。
(defn suma [x sum]
(cond
(= (/ x 3) 0)(let [sum (+ sum x)])
(= (/ x 5) 0)(let [sum (+ sum x)])))
(defn main[]
(def sum 0)
(def x 3)
(while(< x 1001)
(do
(suma sum x)
(let [x (+ x 1)]))
(str "Total = " sum)))
我尝试了几件事,但我无法弄清楚是什么错...... 任何帮助都会被贬低。
由于
编辑:
已修复,问题出在let
,它没有更新数据的值。这是解决方案:
(defn suma [x sum]
(cond
(zero? (mod x 3))(alter-var-root #'sum (constantly (+ sum x)))
(zero? (mod x 5))(alter-var-root #'sum (constantly (+ sum x)))))
(defn main[]
(def sum 0)
(def x 3)
(while(< x 1001)
(do
(suma x sum)
(alter-var-root #'x inc)))
(str "TOTAL = " sum))
答案 0 :(得分:2)
使用序列库的简单解决方案是
(->> (concat
(range 0 1000 3)
(range 0 1000 5))
distinct
(apply +))
如果您想以迭代方式进行,请不要使用while
,这取决于副作用。使用loop
和recur
,它会影响一种称为尾递归的原始递归形式:
(defn divides? [i j]
(zero? (mod j i)))
(loop [answer 0, n 0]
(if (< n 1000)
(recur
(if (or (divides? 3 n) (divides? 5 n))
(+ answer n)
answer)
(inc n))
answer))
以上两者都产生了相同的答案。
答案 1 :(得分:1)
这是使用更多功能样式的大纲。当然,有不止一种方法可以做到这一点(TM)。 :)
> lein repl
user=> (def data (range 20))
user=> data
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
user=> (defn is-mul-3? [x] (zero? (mod x 3)))
user=> (mapv is-mul-3? data)
[true false false true false false true false false true false false true false false true false false true false]
user=> (defn is-mul-5? [x] (zero? (mod x 5)))
user=> (mapv is-mul-5? data)
[true false false false false true false false false false true false false false false true false false false false]
user=> (defn is-mul-3-or-5? [x] (or (is-mul-3? x) (is-mul-5? x)))
user=> (mapv is-mul-3-or-5? data)
[true false false true false true true false false true true false true false false true false false true false]
user=> (def only-3s-and-5s (filterv is-mul-3-or-5? data))
user=> only-3s-and-5s
[0 3 5 6 9 10 12 15 18]
user=> (apply + only-3s-and-5s)
78
这是一个更加不完美的版本。 Clojure值(如let
中的值通常是不可变的)。如果你想要一个类似的东西,你必须使用atom
可变的Java变量:
(ns clj.core
(:gen-class))
(defn is-mul-3? [x]
(zero? (mod x 3)))
(defn is-mul-5? [x]
(zero? (mod x 5)))
(defn is-mul-3-or-5? [x]
(or (is-mul-3? x)
(is-mul-5? x)))
(defn sum-3s-and-5s [limit]
(let [cum-sum (atom 0) ]
(doseq [curr-val (range limit)]
(if (is-mul-3-or-5? curr-val)
(swap! cum-sum + curr-val)))
@cum-sum ))
(defn -main [& args]
(println "cumsum = " (sum-3s-and-5s 20))
)
结果:
~/clj > lein run
cumsum = 78