将 Clojure 解决方案推广到 Euler #1

Generalizing Clojure solution to Euler # 1

Q = 求 1000 以下的所有 3 或 5 的倍数之和。

最简单的答案

(reduce + (filter #(or (== (mod % 3) 0) (== (mod % 5) 0)) (range 1000))) 

正在尝试像下面这样的通用答案

(reduce + (list-nums-divisible-by-all-divisors N div1 div2 ...))
(defn list-nums-divisible-by-all-divisors
    [num & divisors]
    (let [myfn (create-fn divisors)]
        (filter myfn (range num)))) 

这是 2 个除数的 create-fn

(defn create-fn
  [div1 div2]
  #(or (== (mod % div1) 0) (== (mod % div2) 0)))

如何为可变数量的除数编写 create-fn?

这是解决这个问题的正确方法吗?我觉得我应该使用 -> 或 ->> 运算符,而不是这种方式。

此外,我认为这将成为一个通用问题。能否使用可变数量的参数创建并 return 一个函数,然后将其用作匿名函数(具有另一级别的参数)?

提前致谢:-)

我建议更精细一些,构建多个谓词,然后使用 every-pred 组合它们。此函数非常方便地从多个谓词中构建一个谓词。

首先,从柯里化的整除函数开始:

(defn divisible-by? [n]
  (fn [x]
    (zero? (rem x n))))

柯里化只是意味着为了拥有一个函数"taking two arguments",我们首先接受一个参数,然后构建一个接受第二个参数的函数。这些用起来像

((divisible-by? 3) 6) ;;-> true

在这种情况下,我们想要这种行为,因为我们想要 map 一个创建一元谓词的函数,如下所示:

(defn create-fn [divisors]
  (apply every-pred (map divisible-by? divisors)))