循环移位嵌套向量

时间:2013-12-27 18:37:16

标签: clojure clojure-contrib

给定嵌套向量A

[[1 2 3] [4 5 6] [7 8 9]]

我的目标是循环移动行和列。

如果我首先考虑单行转移,我希望

[[7 8 9] [1 2 3] [4 5 6]]

在这种情况下,第3行映射到第一行。

这是由代码

实现的
(defn circles [x i j]
     (swap-rows x i j))

带输入

(circles [[1 2 3] [4 5 6] [7 8 9]] 0 1)

但是,我不确定如何进一步改变列。理想情况下,我想添加到功能圈,并能够移动行或列。虽然我不确定每个班次选择是否只有两个不同的功能是最容易的。

3 个答案:

答案 0 :(得分:4)

(defn circles [xs i j]
  (letfn [(shift [v n]
            (let [n (- (count v) n)]
              (vec (concat (subvec v n) (subvec v 0 n)))))]
    (let [ys (map #(shift % i) xs)
          j  (- (count xs) j)]
      (vec (concat (drop j ys) (take j ys))))))

示例:

(circles [[1 2 3] [4 5 6] [7 8 9]] 1 1)
;= [[9 7 8] [3 1 2] [6 4 5]]

根据您期望执行此操作的频率,使用core.rrb-vector输入向量的大小和要应用的移位可能有意义。 clojure.core.rrb-vector/catvec是相关功能(您也可以使用clojure.core.rrb-vector/subvec进行切片,但实际上可以使用subvec中的常规clojure.corecatvec将{{1}}执行自己的转换。)

答案 1 :(得分:2)

您还可以使用cycle

(defn circle-drop [i coll]
  (->> coll
       cycle
       (drop i)
       (take (count coll))
       vec))

(defn circles [coll i j]
  (let [n (count coll)
        i (- n i)
        j (- n j)]
    (->> coll
         (map #(circle-drop i %))
         (circle-drop j))))

(circles [[1 2 3] [4 5 6] [7 8 9]] 2 1)
;; => [[8 9 7] [2 3 1] [5 6 4]]

答案 2 :(得分:2)

rotate中有一个名为core.matrix的函数(通常用于通用数组/矩阵运算)

rotate的第二个参数可让您选择要旋转的尺寸(0表示行,1表示列)

(use 'clojure.core.matrix)

(def A [[1 2 3] [4 5 6] [7 8 9]])

(rotate A 0 1)
=> [[4 5 6] [7 8 9] [1 2 3]]

(rotate A 1 1)
=> [[2 3 1] [5 6 4] [8 9 7]]