创建表示平方和关系的图形
Creating a graph representing square sum relations
我正在尝试解决平方和问题,更具体地说,是创建一个可以帮助处理关系的函数。
“给定一组整数 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 )
)
测试功能应该return像这样:
(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 and then 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?
计算结果为 [=19= 的对].
我们可以通过传入一组数字来测试它:
(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]}
添加: 原始发帖者建议的更简短的实现使用 for
的 :when
选项:
(defn sqr-sum-rel [A]
(set (for [a A
b A :when (square? (+ a b))]
[a b]))))
我也猜想set中的数不能和自己成pair,也没有必要逆序比较pair成员,因为我们已经知道它们成对了。我会这样更新它:
(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]])
}
}
}
回复:
user> (sq-rel #{1 2 3 4 5 6})
;;=> ([1 3] [4 5] [6 3])
我正在尝试解决平方和问题,更具体地说,是创建一个可以帮助处理关系的函数。
“给定一组整数 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 )
)
测试功能应该return像这样:
(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 and then 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?
计算结果为 [=19= 的对].
我们可以通过传入一组数字来测试它:
(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]}
添加: 原始发帖者建议的更简短的实现使用 for
的 :when
选项:
(defn sqr-sum-rel [A]
(set (for [a A
b A :when (square? (+ a b))]
[a b]))))
我也猜想set中的数不能和自己成pair,也没有必要逆序比较pair成员,因为我们已经知道它们成对了。我会这样更新它:
(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]])
}
}
}
回复:
user> (sq-rel #{1 2 3 4 5 6})
;;=> ([1 3] [4 5] [6 3])