2017-04-02 77 views
0

野外有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]) 

我的代码不能正常工作。它应该返回每种类型的水牛,但我的代码只返回一个空序列。这似乎在逻辑上不正确。它出什么问题了?

+0

这是太含糊。那它不起作用呢?你有调试过吗?我也不知道for循环是否是这里工作的最佳工具。我认为你把Clojure的循环与典型的循环命令混为一谈。 Clojure的for循环就像Python的列表理解。 – Carcigenicate

+0

不工作意味着:结果不正确。它应该返回场上有多少站立,躺着的老水牛。但我的代码只返回一个空序列。这在逻辑上是不正确的。 –

+0

同样,我不认为在这里for循环是适当的。当你想产生一些东西时,你使用for循环。这是它的主要用例。这听起来不像你想在这里做什么。 – Carcigenicate

回答

2

2个主要问题:

  • 使用:while,你告诉它停止只要条件返回false搜索。我相信你的意图是跳过条件错误的情况。为此,您使用:when

  • 您的情况有一个错位的大括号,导致您比较布尔值和数字,这总是错误的。在(= 100 (+ s l o)的末尾添加一个大括号。如果您使用Cursive编写此代码,请确保垂直对齐表单,以便Parinfer可以为您管理花括号。

2

评论

已经采取@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]) 
+0

好的建议,这应该会大大缩短搜索时间。改进是!也许我会通过Criterium运行它们 – Carcigenicate

+0

@Carcigenicate我认为它是一个200的因子:'o'在100以内有一个正确的值;而天真的解决方案平均浪费了100个' s。 – Thumbnail

+0

47.955795 ms vs 3.831184 ms。 – Carcigenicate