我正在寻找满足某些条件的最大数字,这些数字是所有三位数字的乘积。
直截了当的方式是:
(apply max (filter
my-test?
(for [x (range 100 1000)
y (range x 1000)]
(* x y))))
但这涉及计算所有900 * 900产品中的一半。如果我发现,例如,(* 380 455)
与我的my-test?
谓词匹配,我不需要搜索任何因子小于380的产品。当然,我还想从列表中搜索如果我这样做,那就是最小到最小。
在psuedo-Clojure中,我想说这样的话:
(for [x (range 999 99 -1) :while (>= x P)
y (range x 99 -1) :while (>= y P)]
(* x y))
P
是我每次找到匹配时神奇地设置为(min x y)
的内容。
有没有办法在Clojure中做到这一点?
(我知道我可以以对角方式搜索数字,考虑到我已经设置的这个特定问题。但是,我现在正试图解决一般情况下找出如何告诉for循环一些分支机构需要修剪。)
答案 0 :(得分:5)
@omeil建议使用loop
/ recur
进程,这样可以更好地 。 for
循环不是为此而构建的。
(loop [x 999 y 999 min 99 candidates []]
(cond (<= x min) candidates ; exit condition
(<= y min) (recur (dec x) 999 min candidates) ; step x
(my-test? (* x y)) (recur x (dec y) (max min y) (conj candidates (* x y)))
:else (recur x (dec y) min candidates) ; step y
))
答案 1 :(得分:1)
一个非常丑陋的解决方案是使用atom
:
(let [P (atom 0)]
(for [x (range 999 99 -1) :while (>= x @P)
y (range x 99 -1) :while (>= y @P)]
(do
(reset! P (+ x y))
(* x y))))
我认为会阻碍的一点是for
循环并不关心“输出”是什么,所以我无法看到它如何能够原生地获取该信息
“正确”的解决方案可能是一个递归的解决方案,允许您传递(a.k.a.更新)您的最小值。