我正在尝试解决平方和问题,更具体地说,创建一个可以帮助解决关系的函数。
“在给定整数A的情况下,该函数应产生一个包含元组[a b]的关系,如果a和b在A中并且它们的和是一个平方数“
在我的帮助下,我获得了一个帮助函数square?
,该函数测试传递的整数是否为平方数。
(defn square?
[n]
(= n (sqr (isqrt n)))
)
我为此在黑暗中开了枪,但老实说我迷路了。
(defn sqr-sum-rel
[A]
(reduce (fn [a b] (
if (square? (a + b))
[a b]
)) A )
)
测试功能应返回如下内容:
(test? "test" (sqr-sum-rel (set (range 1 11))) #{[5 4] [2 2] [8 8] [4 5] [7 9] [1 3] [3 6] [6 10] [2 7] [1 8] [8 1] [7 2] [10 6] [6 3] [3 1] [9 7]})
我真的对Clojure甚至是函数式编程都是陌生的,因此,希望正确方向的任何指针都可以理解。
要解决此问题,您可以先使用for从集合中生成所有可能的数字对,然后使用filter生成这些对。假设正确实现了square?
,我们将编写一个辅助函数,该函数将成为传递给filter
的第一个参数:
(defn sum-is-square? [coll]
(square? (apply + coll)))
它使用一组数字作为参数,并测试它们的总和是否为square?
。然后我们可以编写完整的函数,如
(defn sqr-sum-rel [A]
(set (filter sum-is-square? (for [a A
b A]
[a b]))))
以一个参数集A
作为参数,并首先生成可以由该集合中的元素形成的所有对,然后仅保留sum-is-square?
的结果为true
的那些对。
我们可以通过传递一组数字来对其进行测试:
(sqr-sum-rel (set (range 1 11)))
;; => #{[8 8] [2 2] [7 2] [5 4] [6 3] [1 3] [1 8] [8 1] [7 9] [2 7] [3 6] [10 6] [4 5] [9 7] [3 1] [6 10]}
添加:原始发布者建议的更简短的实现使用:when
的for
选项:
(defn sqr-sum-rel [A]
(set (for [a A
b A :when (square? (+ a b))]
[a b]))))
我还会猜测集合中的数字不能与自身形成配对,而且也不需要以相反的顺序比较配对成员,因为我们已经知道它们形成了所需的关系。我会这样更新:
(defn sq-rel [a-set]
(seq (for [[x & t] (take-while seq (iterate rest a-set))
y t
:when (square? (+ x y))]
[x y])))
这个或多或少像是当务之急
for (i = 0; i < len; i++) {
for (j = i + 1; j < len; j++)
if (isSquare(a[i] + a[j])) {
res.push([a[i], a[j]])
}
}
}
repl:
user> (sq-rel #{1 2 3 4 5 6})
;;=> ([1 3] [4 5] [6 3])