Clojure,对向量列表求和,沿途记录位置

Clojure, sum a list of vectors, recording positions along the way

假设我有一个向量列表

([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)) 将下一次递归调用中的第一个元素替换为上次调用中前两个向量的和。

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

(+ 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])

最后,为了return只有这个序列中的唯一元素,你可以使用set:

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