Clojure的宏的正确使用方法
野外有100只水牛。 在场上有100只whis子。 每个站立的水牛吃5个威士忌。 每个躺着的水牛吃3个威士忌。 每3只老水牛吃1个威士忌。 这个字段上有多少种水牛?Clojure的宏的正确使用方法
这是我的Clojure代码来解决这个问题:
;; s: number of Standing buffaloes
;; l: number of Lying buffaloes
;; o: number of Old buffaloes
(for [s (range 101) l (range 101) o (range 101)
:while (and
(= 100 (+ s l o)
(= 100 (+ (* s 5) (* l 3) (* o 1/3)))))]
[s l o])
我的代码不能正常工作。它应该返回每种类型的水牛,但我的代码只返回一个空序列。这似乎在逻辑上不正确。它出什么问题了?
2个主要问题:
使用
:while
,你告诉它停止只要条件返回false搜索。我相信你的意图是跳过条件错误的情况。为此,您使用:when
。您的情况有一个错位的大括号,导致您比较布尔值和数字,这总是错误的。在
(= 100 (+ s l o)
的末尾添加一个大括号。如果您使用Cursive编写此代码,请确保垂直对齐表单,以便Parinfer可以为您管理花括号。
评论
已经采取@Carcigentate's advice到作出正确,您可以使其快速儿这样的:
(for [s (range 101), l (range (- 101 s)) :let [o (- 100 s l)]
:when (= 100 (+ (* s 5) (* l 3) (* o 1/3)))]
[s l o])
好的建议,这应该会大大缩短搜索时间。改进是!也许我会通过Criterium运行它们 – Carcigenicate
@Carcigenicate我认为它是一个200的因子:'o'在100以内有一个正确的值;而天真的解决方案平均浪费了100个' s。 – Thumbnail
47.955795 ms vs 3.831184 ms。 – Carcigenicate
这是太含糊。那它不起作用呢?你有调试过吗?我也不知道for循环是否是这里工作的最佳工具。我认为你把Clojure的循环与典型的循环命令混为一谈。 Clojure的for循环就像Python的列表理解。 – Carcigenicate
不工作意味着:结果不正确。它应该返回场上有多少站立,躺着的老水牛。但我的代码只返回一个空序列。这在逻辑上是不正确的。 –
同样,我不认为在这里for循环是适当的。当你想产生一些东西时,你使用for循环。这是它的主要用例。这听起来不像你想在这里做什么。 – Carcigenicate