For loop 如何在Clojure for循环运行时更改:while条件?
我正在搜索满足某些条件的最大数字,从所有三位数的乘积的数字集合中 简单的方法是:For loop 如何在Clojure for循环运行时更改:while条件?,for-loop,clojure,For Loop,Clojure,我正在搜索满足某些条件的最大数字,从所有三位数的乘积的数字集合中 简单的方法是: (apply max (filter my-test? (for [x (range 100 1000) y (range x 1000)] (* x y)))) 但这需要计算所有900*900产品的一半。如果我发现,例如,(*380 455)匹配我的测试?谓词,我不需要搜索任何因子小于380的产品
(apply max (filter
my-test?
(for [x (range 100 1000)
y (range x 1000)]
(* x y))))
但这需要计算所有900*900产品的一半。如果我发现,例如,(*380 455)
匹配我的测试?
谓词,我不需要搜索任何因子小于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循环它的一些分支需要修剪。)一个非常丑陋的解决方案是使用
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
循环并不真正关心“输出”是什么,因此我无法看到它如何能够以本机方式获取该信息
“正确”的解决方案可能是一种递归解决方案,它允许您传入(也称为更新)您所知道的最小值。@omeil建议使用
循环
/递归
过程,效果更好<代码>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
))
(循环[x 999 y 999 min 99个候选项[]]
(cond)(这接近于我在你回答后一分钟得出的结论。我需要在for循环的第一个参数中加入一个:when(我的测试?(*x y))
,这样P只能在成功匹配时重置。我同意这感觉不是很“Clojure-y”.从变量的问题和约束条件,我推断您正试图解决Project Euler的#4,在这种情况下,您希望for
返回单个结果。在这种情况下,为什么要使用for
(这不是“for”循环,而是一个列表理解,旨在返回列表)通过loop
/recur
?正确的答案不一定是我第一次找到的答案。虽然作为我自己的练习,我打算尝试一下loop
/recur
。@omiel是对的,这是一个更好的方法。下面是一个方法,列出了我需要获得(max)的候选人列表
of:(循环[x999 y999 min 99候选者[])(cond(你应该添加它作为答案。另外,习惯用法是使用:else
作为cond的总括,如果我找到,例如(*380 455)匹配我的my test?谓词,我不需要搜索任何因子小于380的产品-如果您的目标是找到满足某个谓词的两个数字的最大乘积,则这似乎是完全错误的。例如,(*379 999)
仍然大于(*380 455)
。在本例中,您真正能做的就是跳过两个被乘数都小于380的对。