[英]How can I change the :while condition on a Clojure for-loop while it is running?
I'm searching for the biggest number meeting some condition, out of the set of numbers that are the product of all three-digit numbers. 我正在从所有三位数数字的乘积中搜索满足某些条件的最大数字。
The straightforward way is this: 直接的方法是这样的:
(apply max (filter
my-test?
(for [x (range 100 1000)
y (range x 1000)]
(* x y))))
But this involves calculating half of all 900*900 products. 但这涉及计算所有900 * 900产品的一半。 If I find, eg,
(* 380 455)
matches my my-test?
如果我发现例如
(* 380 455)
符合my-test?
predicate, I don't need to search any products where either factor is less than 380. Of course, I will also want to search the list from the biggest to the smallest if I'm doing this. 谓词,我不需要搜索任何因子均小于380的产品。当然,如果要这样做,我也想从最大到最小搜索列表。
In psuedo-Clojure, I want to say something like this: 在psuedo-Clojure中,我想说这样的话:
(for [x (range 999 99 -1) :while (>= x P)
y (range x 99 -1) :while (>= y P)]
(* x y))
where P
is something I magically set to (min xy)
each time I find a match. 其中
P
是我每次找到匹配项时都会神奇地设置为(min xy)
的值。
Is there a way to do this in Clojure? Clojure有办法做到这一点吗?
(I realize I could search the numbers in a diagonal fashion, given this specific problem I've set up. However, I'm now trying to solve for the general case of figuring out how to tell the for-loop that some its branches need pruned.) (考虑到我已经设置的这个特定问题,我意识到我可以对角线形式搜索数字。但是,我现在正在尝试解决一般情况,以弄清楚如何告诉for循环某些分支需要修剪。)
@omeil suggested a loop
/ recur
process, and this works much better. @omeil建议一
loop
/ recur
的过程,而这个效果要好得多。 for
loops just aren't built for this. 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
))
A very ugly solution would be to use an atom
: 一个非常丑陋的解决方案是使用
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))))
One thing that I think will get in the way is that the for
loop doesn't really care what the "output" is, so I am unable to see how it would be able to get that information natively. 我想会遇到的一件事是
for
循环并不真正在乎“输出”是什么,因此我无法看到它将如何从本地获取信息。
The "right" solution is probably a recursive one that allows you to pass in (aka update) your minimum as you know more. “正确”的解决方案可能是一种递归解决方案,它使您可以了解更多而传递(又称为更新)最小值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.