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

Jac*_*ans 1 lisp recursion tail-recursion vector clojure

说我有一个向量列表

([0 0] [1 0] [1 0] [1 0])
Run Code Online (Sandbox Code Playgroud)

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

                [0 0]
[0 0] + [1 0] = [1 0]
[1 0] + [1 0] = [2 0]
[2 0] + [1 0] = [3 0]
Run Code Online (Sandbox Code Playgroud)

提供4个独特的职位.

([0 0] [1 0] [2 0] [3 0]) 
Run Code Online (Sandbox Code Playgroud)

知道如何在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))))))
Run Code Online (Sandbox Code Playgroud)

(conj (rest (rest dirs))替换与所述第一两个矢量从最后一次调用的总和下一递归调用所述第一元件.

Sam*_*tep 6

要将两个数字组合在一起,您可以使用该+功能,如您所知:

(+ 2 1)
;;=> 3
Run Code Online (Sandbox Code Playgroud)

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

(mapv + [1 0] [1 0])
;;=> [2 0]
Run Code Online (Sandbox Code Playgroud)

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

(reduce #(mapv + %1 %2) [[0 0] [1 0] [1 0] [1 0]])
;;=> [3 0]
Run Code Online (Sandbox Code Playgroud)

或者,使用以下内容替换该函数文字partial:

(reduce (partial mapv +) [[0 0] [1 0] [1 0] [1 0]])
;;=> [3 0]
Run Code Online (Sandbox Code Playgroud)

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

(reductions (partial mapv +) [[0 0] [1 0] [1 0] [1 0]])
;;=> ([0 0] [1 0] [2 0] [3 0])
Run Code Online (Sandbox Code Playgroud)

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

(set (reductions (partial mapv +) [[0 0] [1 0] [1 0] [1 0]]))
;;=> #{[0 0] [1 0] [3 0] [2 0]}
Run Code Online (Sandbox Code Playgroud)