3

我正在阅读Clojure in Action 这本书,并且给出了与下面类似的代码,该函数返回m以下的所有数对,其总和为素数(假设素数?已给出):

(defn pairs-for-primes [m]
  (let [z (range 0 m)]
    (for [a z b z :when (prime? (+ a b))]
      (list a b))))

将如何推广它以返回所有低于 m 且总和为素数的数的 n 元组?

(defn all-ntuples-below [n m]
...
4

2 回答 2

2

for可用于笛卡尔积的一种“特殊情况”,您可以在编译时提前知道集合。由于您实际上并不知道您想要乘积的集合,因此您需要使用真正的笛卡尔积函数。例如,使用clojure.math.combinatorics,您可以编写

(defn pairs-for-primes [m n]
  (let [z (range 0 m)
        tuples (apply cartesian-product (repeat n z))]
    (filter #(prime? (apply + %)) tuples)))

但也许您的问题是关于如何实现笛卡尔积?这并不难,虽然下面的版本性能不是很好:

(defn cartesian-product [sets]
  (cond (empty? sets) (list (list))
        (not (next sets)) (map list (first sets))
        :else (for [x (first sets)
                    tuple (cartesian-product (rest sets))]
                (cons x tuple))))
于 2013-02-08T23:46:46.363 回答
1

您可以take这样做(因为pairs-for-primes返回一个序列take只会导致它计算所需的项目数)

(defn all-ntuples-below [n m]
  (take n (pairs-for-primes m)))
于 2013-02-09T07:27:58.397 回答