给定嵌套向量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)
但是,我不确定如何进一步改变列。理想情况下,我想添加到功能圈,并能够移动行或列。虽然我不确定每个班次选择是否只有两个不同的功能是最容易的。
答案 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.core
,catvec
将{{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]]