将向量传递到循环中的问题

时间:2013-12-12 17:05:08

标签: clojure

我一直在使用Rosalind problems来学习clojure,下面的代码是mortal rabbits问题解决方案的一部分。我的解决方案是创建一个名为兔子的记录,以跟踪每只兔子。兔子记录将存储在一个载体中,我会在几个月内循环,并在每个月通过添加新的兔子(add-rabbits)并过滤死亡的兔子(remove-rabbits)来更新载体。

这听起来很简单,但我遇到了一个我似乎无法摆动的问题:当我尝试将更新后的矢量传回循环时,我遇到了一个错误,我想知道什么是什么继续我确定这是其中一个我会重新提出的错误,它会非常明显但是嘿,那就是新语言会发生什么呢?任何见解都将不胜感激。

;define a rabbit record with birth and death months
(defrecord rabbit [born dies] )
; function that calculates number of living rabbits
(defn iter-rabbit2 [months lifemonths]
  (letfn [ (add-rabbits [month rabbits]
           ;add-rabbits looks for reproductively active rabbits and creates new rabbits
               (let [num-repr-rabbits (count (filter #(>= (+ month 1) (.born %)) rabbits))
                     new-rabbits (vec (repeat num-repr-rabbits (rabbit. (+ month 1) (+ month lifemonths 1))))]
                    (do
                     (println "rabbits" rabbits)  ; for debugging
                     (println "rabbits type " (type rabbits))
                     (if (seq new-rabbits)
                         (apply conj (vec rabbits) (vec new-rabbits))
                         (rabbits)))))

          (remove-rabbits [month rabbits]
          ;remove rabbits filters the rabbits vector of dying rabbits
                (let [livingrabbits (vec (filter #(not= month (.dies %)) rabbits ))]
                     (do
                       (println "remove rabbits rabbits" livingrabbits) ;for debugging
                       (println (type livingrabbits))
                       (livingrabbits)))) ]

   (loop [month 0
          lifemonth lifemonths
          rabbits  [(rabbit. month lifemonth)] ]

    (if (= month months)
        [rabbits]
        (recur (+ month 1)
               (+ lifemonth 1)
               ( ->> rabbits
                      (add-rabbits month)
                      (remove-rabbits month)
                      (apply vector)
                      ))))))
(iter-rabbit2 5 6)

我得到的错误如下:     ArityException传递给的参数arg(0)错误:PersistentVector
    clojure.lang.AFn.throwArity(AFn.java:437)

2 个答案:

答案 0 :(得分:3)

在移除兔子的最后,你有(livingrabbits)调用livingrabbits作为带有0个参数的IFn。在此之上,您将livingrabbits定义为从兔子过滤的矢量。调用为IFn时的向量需要一个或两个参数:要查找和返回的索引,以及可选的默认值(如果该索引不存在)。

同样,在add-rabbit的末尾你可以打电话给(rabbits)。在函数底部的递归中,似乎兔子也应该是一个向量,所以它也被调用的参数太少了。

我认为你并不是要调用活着的兔子/兔子,而是要归还它们。您可以简单地删除无关的parens(除非您打算将兔子放在父数据结构中,在这种情况下,您可以用方括号替换parens)。

答案 1 :(得分:0)

我可以提出一些建议。

  • 您不需要为每只兔子创建记录。所有 同年出生的兔子也表现出同样的行为。你只需要 算他们。
  • 使用你的代码,正如上面提到的noisesmith所暗示的那样 数字错误:它们与问题页面上给出的解决方案不匹配。
  • 对于这样的问题,Clojure成语是提出来的 解决方案作为一个懒惰的序列。你可以找到一个优秀的帐户 Halloway和。的 Programming Clojure 第4章中的这一点 Bedra。你的问题的一个很好的起点是克里斯托弗格兰德对斐波纳契数列的解决方案。

这是(来自记忆)。

(defn fibo-base []
  (let [step (fn [[a b]] [b (+ a b)])]
    (map first (iterate step [0 1]))))

总的来说,我发现更容易学习Clojure解决方案可用的问题。以下是有用的: