像蛇一样猛击


21

想法

我们之前已经完成了矩阵螺旋旋转,完整旋转甚至对角旋转,但据我所知,还没有蛇旋转

什么是蛇旋转?

想象一下矩阵的行来回蛇行,它们之间的分隔线就像长队列的分隔线一样:

    +--------------+
      1  2  3  4  5|
    +------------  |
    |10  9  8  7  6|
    |  +-----------+
    |11 12 13 14 15|
    +------------  |
     20 19 18 17 16|
    +--------------+

现在,假设将这些项目旋转2。每个项目都会前进,就像人们在一条直线上移动一样,最后的项目会溢出并回到起点:

    +--------------+
-->  19 20  1  2  3|
    +------------  |
    | 8  7  6  5  4|
    |  +-----------+
    | 9 10 11 12 13|
    +------------  |
<--  18 17 16 15 14|
    +--------------+

如果行数奇数,它将从右边退出,但仍会换行到开头。例如,这是3轮换:

    +--------------+
      1  2  3  4  5|
    +------------  |
    |10  9  8  7  6|
    |  +-----------+
    |11 12 13 14 15
    +--------------+


    +--------------+
-->  13 14 15  1  2|
    +------------  |
    | 7  6  5  4  3|
    |  +-----------+
    | 8  9 10 11 12  -->
    +--------------+

负旋转会使您倒退。这是-2旋转:

    +--------------+
<--   3  4  5  6  7|
    +------------  |
    |12 11 10  9  8|
    |  +-----------+
    |13 14 15  1  2  <--
    +--------------+

挑战

您的函数或程序将接受2种输入,采用任何方便的格式:

  • 矩阵
  • 一个整数(正数或负数),指示将其旋转多少个位置。

它将返回:

  • 旋转矩阵

笔记:

  • 代码高尔夫。最少的字节数获胜。
  • 矩阵不必为正方形,但将至少包含2行2列
  • 正整数将使第1行向右旋转
  • 负整数将使第1行向左旋转
  • 如果方便,您可以反转正/负转数的含义
  • 旋转数可以大于项目数。在这种情况下,它将包装。也就是说,它等于项目数的模数。
  • 矩阵将仅包含整数,但可以包含任何整数,包括重复

测试用例

格式:

  • 矩阵
  • 转数
  • 预期收益

4 5
6 7

1

6 4
7 5

2  3  4  5
6  7  8  9
10 11 12 13

-3

5  9  8  7
12 11 10 6
13 2  3  4 

8 8 7 7
5 5 6 6

10

5 5 8 8
6 6 7 7

4
+/-的含义相反。我认为入口应该保持在左上方。
约拿

7
这肯定需要Python的答案。
640KB

Answers:


7

果冻,10 字节

UÐeẎṙṁ⁸UÐe

双向链接,左侧接受marix,右侧接受旋转整数(使用正/负的相反含义)

在线尝试!

怎么样?

UÐeẎṙṁ⁸UÐe - Link: matrix of integers, M; integer, R
 Ðe        - apply to even indices of M:
U          -   reverse each
   Ẏ       - tighten
    ṙ      - rotate left by R
     ṁ     - mould like:
      ⁸    -   chain's left argument, M
        Ðe - apply to even indices:
       U   -   reverse each

6

[R 121个 110 101字节

function(m,n,o=t(m)){o[,j]=o[i<-nrow(o):1,j<-c(F,T)];o[(seq(o)+n-1)%%sum(1|o)+1]=o;o[,j]=o[i,j];t(o)}

在线尝试!

演练

function(m,n) {           # Input: m - matrix, n - shift
  o <- t(m)               # Transpose the matrix, since R works in column-major order
                          # while our snake goes in row-major order
  i <- nrow(o):1          # Take row indices in reverse
  j <- c(F,T)             # Take even column indices (FALSE, TRUE, FALSE, TRUE, ...)
  o[,j] <- o[i,j]         # "Normalize" the matrix by reversing every second column
  o[(seq(o)+n-1) %%       # Perform the shift: add n-1 to indices,
    length(o)+1] <- o     # Modulo sequence length, and +1 again
  o[,j] <- o[i,j]         # Reverse even columns again to return to snake form
  t(o)                    # Transpose the matrix back to orginal shape and return
}

3

Python 3.8(pre-releasSSSse),119个字节

lambda m,r,n=-1:[[m[(k:=(j+(s:=r+i)//w)%h)][::n**k][s%w]for i in range(w:=len(m[0]))][::n**j]for j in range(h:=len(m))]

接受的未命名函数matrix, rotation产生新矩阵。
使用相反的旋转符号。

在线尝试!

怎么样?

我们n=-1预先设置为以后保存括号,并将矩阵设为m,将旋转设为r

新矩阵的尺寸与m- 相同,宽度为ww:=len(m[0])),高度为hh:=len(m))。

此矩阵的每隔一行都反转([::n**j])。

通过m使用当前元素row i,和column,j... 计算原始值中的行和列来查找值。

我们设置sr+ik(j+s//w)%hk是要访问的当前元素的原始行。

为了方便地从右侧访问奇数索引的行,我们在访问其元素之前使用([:n**k])反转了这些行,这意味着感兴趣的元素位于s%w


3

J41 30 21字节

-11字节感谢乔纳!

-9个字节感谢FrownyFrog&ngn!

$@]t@$(|.,@t=.|.@]/\)

在线尝试!

倒转 +/-


1
30个字节,不+/-逆转,但仍使用助手:$@]t@$(|.,@(t=.#\,`(|.@,)/.]))在线试试吧!
乔纳

校正:+/-仍然反转。
约拿

@Jonah现在是J!我记得最近看到您在交替反转中应用了相同的技巧,但显然已经忘记了。谢谢!尝试时,&.我一直都在松开左键,这就是为什么我放弃了。
Galen Ivanov

1
21个字节,thx @ngn
FrownyFrog

@FrownyFrog哇,现在是初始大小的一半。我觉得很蠢...谢谢!
Galen Ivanov

2

JavaScript(Node.js),102字节

将输入作为(matrix)(integer)。整数的符号含义相反。

m=>n=>(g=m=>m.map(r=>r.sort(_=>~m,m=~m)))(m.map(r=>r.map(_=>a[(l+n++%l)%l]),l=(a=g(m).flat()).length))

在线尝试!

辅助功能

辅助功能 G 用于通过反转奇数索引处的行来“捕捉”或“取消捕捉”矩阵。

g = m =>        // m[] = input matrix
  m.map(r =>    // for each row r[] in m[]:
    r.sort(_ => //   sort r[]:
      ~m,       //     using either 0 (don't reverse) or -1 (reverse)
      m = ~m    //     and toggling m before each iteration
                //     (on the 1st iteration: m[] is coerced to 0, so it yields -1)
    )           //   end of sort()
  )             // end of map()

主功能

m => n =>                    // m[] = matrix, n = integer
  g(                         // invoke g on the final result
    m.map(r =>               //   for each row r[] in m[]:
      r.map(_ =>             //     for each entry in r[]:
        a[(l + n++ % l) % l] //       get the rotated value from a[]; increment n
      ),                     //     end of inner map()
      l = (                  //     l is the length of a[]:
        a = g(m).flat()      //       a[] is the flatten result of g(m)
      ).length               //       (e.g. [[1,2],[3,4]] -> [[1,2],[4,3]] -> [1,2,4,3])
    )                        //   end of outer map()
  )                          // end of call to g


1

木炭,36字节

FEθ⎇﹪κ²⮌ιιFι⊞υκIE⪪Eυ§υ⁻κηL§θ⁰⎇﹪κ²⮌ιι

在线尝试!链接是详细版本的代码。说明:

Eθ⎇﹪κ²⮌ιι

反转输入的交替行。

F...Fι⊞υκ

展平数组。

Eυ§υ⁻κη

旋转展平的阵列。

⪪...L§θ⁰

将数组拆分回行。

E...⎇﹪κ²⮌ιι

反转备用行。

I...

将每个条目转换为字符串并以默认输出格式输出,该格式是每行一个数字,行以双倍行距隔开。(使用分隔符进行格式化会花费分隔符的时间。)



1

Japt,28个字节

mÏ%2©XÔªX
c éV òUÎl
W©UªßV1V

试试吧

阿诺尔德港口的答案。最大的挑战是创建可重用的功能。特别是,有一个辅助函数可以使每隔一行相反。我采用的方法是进行递归调用,具体取决于是否设置了变量。

转译的JS:

// U: first input argument (matrix)
// m: map it through a function
U = U.m(function(X, Y, Z) {
  // if the row index is even, don't alter it
  // if the row index is odd, reverse it (w)
  return Y % 2 && X.w() || X
});
V = U
  // flatten the matrix
  .c()
  // shift by the amount specified in second argument
  .é(V)
  // partition back to matrix
  .ò(
    // the number of columns should be the same as input
    U.g().l()
  );
// if W is specified, return the result from the first line
W && U ||
  // otherwise, make a recursive call with the shifted matrix
  rp(V, 1, V)

1

Python 3,94个字节

lambda m,n:g(roll(g(m),n))
g=lambda b:[b[i][::(-1)**i]for i in r_[:len(b)]]
from numpy import*

在线尝试!

使用了乔纳森·艾伦回答中的奇数行反转。

lambda m,n:g(roll(g(m),n))  #reverse odd rows, shift elements, then reverse odd rows again.
g=lambda b:[b[i][::(-1)**i] #reverse odd rows
    for i in r_[:len(b)]]   #r_[:x] = range(x)
from numpy import*          #roll() and r_[]


1

C#(Visual C#交互式编译器),141个字节

a=>n=>{for(dynamic l=a.Length,w=a.GetLength(1),i=l,j,b=a.Clone();i-->0;)a[(j=(i+n%l+l)%l)/w,j/w%2<1?j%w:w-j%w-1]=b[i/w,i/w%2<1?i%w:w-i%w-1];}

在线尝试!

由于@someone,共-5个字节!

对输入矩阵执行就地修改的匿名函数。

一个循环遍历单元。您可以使用以下公式从上至下和从左至右进行扫描:

  • row=i/w
  • col=i%w

哪里i是循环计数器,w是列数。以蛇形扫描时,此变化略有不同。

  • row=i/w
  • col=i%w (第0、2、4等行)
  • col=w-i%w-1 (第1、3、5等行)

要注意的另一件事是,%C#中的in不会像其他某些语言中那样转换为正值。需要几个额外的字节来解决这个问题。

// a: input matrix
// n: number of cells to rotate
a=>n=>{
  for(
    // l: total number of cells
    // w: number of columns
    // i: loop index
    // j: offset index
    // b: copy of input matrix
    dynamic
      l=a.Length,
      w=a.GetLength(1),
      i=l,j,
      b=a.Clone();
    // iterate from i down to 0
    i-->0;
  )
    // calculate the offset `j` and use
    // the above formulas to index
    // into `a` for setting a value
    a[
      (j=(i+n%l+l)%l)/w,
      j/w%2<1?j%w:w-j%w-1
    ]=
    // use the un-offset index `i` and
    // the above formulas to read a
    // value from the input matrix
    b[
      i/w,
      i/w%2<1?i%w:w-i%w-1
    ];
}

通过将声明与合并,可以节省3个字节dynamic。评论也 在线尝试!
我的代词是monicareinstate

好的:)该声明也可以移入循环。我倾向于var打高尔夫球,它不允许您声明变量列表。大概为什么我错过了这个。接得好!
dana

y完全摆脱以节省2个字节:在线尝试!
我的代词是monicareinstate,

@someone-谢谢!
dana

具有1d阵列和宽度输入的TIO 135
我的代名词是monicareinstate,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.