Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
For loop 如何在Clojure for循环运行时更改:while条件?_For Loop_Clojure - Fatal编程技术网

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的对。