用于查找x是否为y的倍数的函数

时间:2012-06-19 02:01:52

标签: clojure

查看下面的功能。我想传递一个因子向量,并测试向量中的任何元素是x的因子。我该怎么做?

(defn multiple?
  "Takes a seq of factors, and returns true if x is multiple of any factor."
  ([x & factors] (for [e m] ))
  ([x factor] (= 0 (rem x factor))))

4 个答案:

答案 0 :(得分:1)

您可以尝试使用somemap

(defn multiple? [x & factors]
  (some zero? (map #(rem x %) factors)))

如果所有测试都失败,some也返回nil,如果您需要实际返回false,则可以在其中放置true?

(defn multiple? [x & factors]
  (true? (some zero? (map #(rem x %) factors))))

请注意,some短路和map是懒惰的,因此multiple?会在找到匹配后立即停止。例如以下代码测试序列1,2,3,4,...

=> (apply multiple? 10 (map inc (range)))
true

显然,只有当multiple?不对序列中的每个数字进行测试时,此计算才会终止。

答案 1 :(得分:1)

您只能使用some解决此问题。

=> (defn multiple? [x factors]
 (some #(zero? (rem x %)) factors))
#'user/multiple?
=> (= true (multiple? 10 [3 4]))
false
=> (= true (multiple? 10 [3 4 5 6]))
true

some将停在第一个因素。

答案 2 :(得分:0)

尝试使用显式尾递归:

(defn multiple? [x factors]
  "if any of the elements in the vector is a factor of x"
  (loop [factors factors]
        (cond (empty? factors) false
              (zero?  (rem x (first factors))) true
              :else   (recur (rest factors)))))

上述解决方案的优点包括:一旦发现向量中的任何元素是x的因子,它将立即停止,而不迭代整个向量;由于使用了尾递归,它的效率很高,并且在恒定的空间内运行;它直接返回一个布尔结果,不需要考虑返回nil的情况。像这样使用它:

(multiple? 10 [3 4])
=> false

(multiple? 10 [3 4 5 6])
=> true

如果你想避免显式传递一个向量的需要(用于调用这样的过程:(multiple? 10 3 4 5 6))),那么只需在参数列表中添加一个&,就像它在问题

答案 3 :(得分:0)

更多 Clojurian 方法是编写一个更通用的函数:它不会回答真/假问题,而是返回x的所有因子。而且因为序列是懒惰的,所以如果你想知道它是否为空,它几乎同样有效。

(defn factors [x & fs]
  (for [f fs :when (zero? (rem x f))] f))

(factors 5 2 3 4)
=> ()

(factors 6 2 3 4) 
=> (2 3)

然后您只需使用empty?

即可回答原始问题
(empty? (factors 5 2 3 4))
=> true

(empty? (factors 6 2 3 4))
=> false