Clojure,总结一个向量列表,记录沿途的位置

时间:2016-07-02 19:10:59

标签: recursion vector clojure lisp tail-recursion

说我有一个载体列表

([0 0] [1 0] [1 0] [1 0])

我希望能够将矢量列表添加到一起并记录每个独特的位置。

                [0 0]
[0 0] + [1 0] = [1 0]
[1 0] + [1 0] = [2 0]
[2 0] + [1 0] = [3 0]

提供4个独特的职位。

([0 0] [1 0] [2 0] [3 0]) 

我知道如何在Clojure中实现这一目标吗?

我尝试过以下代码,但是对于大量的向量,它会溢出:(

(defn add-vectors [vectors]
  (let [[a b] vectors]
    (vec(map + a b))))

(defn get-positions [dirs positions]
  (if (empty? (rest dirs))
    (set positions)
    (do
      (let [next-pos (add-vectors (take 2 dirs))]
        (get-directions (conj (rest (rest dirs)) next-pos) (conj positions next-pos))))))

(conj (rest (rest dirs))使用上次调用中前两个向量的总和替换下一个递归调用中的第一个元素。

1 个答案:

答案 0 :(得分:6)

要将两个数字加在一起,您可以使用+函数,如您所知:

(+ 2 1)
;;=> 3

要将两个向量添加到一起,您可以使用mapv函数使用+将两个向量压缩在一起:

(mapv + [1 0] [1 0])
;;=> [2 0]

要在一系列向量中执行此向量加法的左侧折叠,您可以使用reduce

(reduce #(mapv + %1 %2) [[0 0] [1 0] [1 0] [1 0]])
;;=> [3 0]

或者,使用partial替换该函数文字:

(reduce (partial mapv +) [[0 0] [1 0] [1 0] [1 0]])
;;=> [3 0]

要获得此左侧折叠的所有中间步骤,您可以使用reductions

(reductions (partial mapv +) [[0 0] [1 0] [1 0] [1 0]])
;;=> ([0 0] [1 0] [2 0] [3 0])

最后,要仅返回此序列中的唯一元素,您可以使用set

(set (reductions (partial mapv +) [[0 0] [1 0] [1 0] [1 0]]))
;;=> #{[0 0] [1 0] [3 0] [2 0]}