2017-04-02 79 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