Slither Like a Snake


21

Ý tưởng

Chúng tôi đã thực hiện các ma trận xoắn ốc trước đây, và các phép quay đầy đủ, và thậm chí cả các đường chéo chéo , nhưng không, như tôi có thể tìm thấy, xoay rắn !

Một vòng quay rắn là gì?

Hãy tưởng tượng các hàng của một ma trận bắt đầu qua lại, với các vạch chia giữa chúng giống như các vạch chia của hàng dài:

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

Bây giờ hãy tưởng tượng xoay các vật phẩm này bằng 2. Mỗi vật phẩm tiến lên, như mọi người di chuyển trong một dòng và các vật phẩm ở cuối tràn ra và trở về đầu:

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

Nếu có một số hàng lẻ, nó sẽ thoát khỏi bên phải, nhưng vẫn quấn vào đầu. Ví dụ: đây là một vòng quay 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  -->
    +--------------+

Một vòng quay tiêu cực sẽ đưa bạn trở lại. Đây là một vòng quay -2:

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

Các thách thức

Chức năng hoặc chương trình của bạn sẽ có 2 đầu vào, ở bất kỳ định dạng thuận tiện nào:

  • Một ma trận
  • Một số nguyên (dương hoặc âm) cho biết có bao nhiêu vị trí để xoay nó.

Nó sẽ trở lại:

  • Ma trận xoay

Ghi chú:

  • Mã golf. Ít byte nhất sẽ thắng.
  • Ma trận không cần phải là hình vuông, nhưng sẽ chứa ít nhất 2 hàng và 2 cột
  • Số nguyên dương sẽ xoay hàng 1 về phía bên phải
  • Số nguyên âm sẽ xoay hàng 1 về phía bên trái
  • Bạn có thể đảo ngược ý nghĩa của các số xoay dương / âm, nếu thuận tiện
  • Số vòng quay có thể lớn hơn số lượng mặt hàng. Trong trường hợp đó, nó sẽ bọc lại. Đó là, nó sẽ tương đương với số modulo số lượng vật phẩm.
  • Ma trận sẽ chỉ chứa các số nguyên, nhưng nó có thể chứa bất kỳ số nguyên nào, kể cả lặp lại

Các trường hợp thử nghiệm

Định dạng:

  • Ma trận
  • Số vòng quay
  • Giá trị lợi nhuận dự kiến

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
Ý nghĩa đảo ngược của +/- là tốt. Tôi nghĩ rằng lối vào nên ở phía trên bên trái mặc dù.
Giô-na

7
Điều này chắc chắn cần một câu trả lời trong Python.
640KB

Câu trả lời:


7

Thạch , 10 byte

UÐeẎṙṁ⁸UÐe

Liên kết dyadic chấp nhận marix ở bên trái và số nguyên xoay ở bên phải (sử dụng ý nghĩa ngược của dương / âm)

Hãy thử trực tuyến!

Làm sao?

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 byte

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)}

Hãy thử trực tuyến!

Hướng dẫn

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 byte

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

Một hàm không tên chấp nhận matrix, rotationmang lại ma trận mới.
Sử dụng dấu hiệu xoay ngược lại.

Hãy thử trực tuyến!

Làm sao?

Chúng tôi thiết lập n=-1trả trước để lưu vào dấu ngoặc đơn sau đó và lấy ma trận mvà xoay vòng làmr .

Một ma trận mới được xây dựng với cùng kích thước với m- với chiều rộng là w( w:=len(m[0])) và chiều cao của h(h:=len(m) ).

Mọi hàng khác của ma trận này được đảo ngược ([::n**j] ).

Các giá trị được tra cứu bằng cách tính toán hàng và cột của chúng trong bản gốc, msử dụng hàng phần tử hiện tại ivà cột,j ...

Chúng tôi đặt sđể r+ikđể (j+s//w)%h.klà hàng của bản gốc để truy cập cho phần tử hiện tại của chúng tôi.

Để dễ dàng truy cập các hàng được lập chỉ mục lẻ từ bên phải, chúng tôi đảo ngược các hàng đó trước khi truy cập các phần tử của chúng (với [:n**k]), điều này có nghĩa là phần tử quan tâm đang ở s%w.


3

J , 41 30 21 byte

-11 byte nhờ Jonah!

-9 byte nhờ FrownyFrog & ngn!

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

Hãy thử trực tuyến!

Đảo ngược +/-


1
30 byte, +/- không bị đảo ngược, nhưng vẫn sử dụng trình trợ giúp: $@]t@$(|.,@(t=.#\,`(|.@,)/.]))( Dùng thử trực tuyến! )
Jonah

hiệu chỉnh: +/- vẫn đảo ngược.
Giô-na

@Jonah Bây giờ là J! Tôi nhớ đã thấy bạn áp dụng thủ thuật tương tự với sự đảo chiều xen kẽ gần đây, nhưng dường như đã quên nó. Cảm ơn bạn! Khi cố gắng &.tôi đã mất lập luận bên trái mọi lúc, đó là lý do tại sao tôi đã từ bỏ.
Galen Ivanov

1
21 byte , thx @ngn
FrownyFrog

@FrownyFrog Wow, bây giờ là một nửa kích thước ban đầu. Tôi cảm thấy ngu ngốc ... Cảm ơn!
Galen Ivanov

2

JavaScript (Node.js) , 102 byte

Đưa đầu vào là (matrix)(integer). Ý nghĩa của dấu của số nguyên được đảo ngược.

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))

Hãy thử trực tuyến!

Chức năng trợ giúp

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

Chức năng chính

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

Than , 36 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

Eθ⎇﹪κ²⮌ιι

Đảo ngược hàng thay thế của đầu vào.

F...Fι⊞υκ

Làm phẳng các mảng.

Eυ§υ⁻κη

Xoay mảng dẹt.

⪪...L§θ⁰

Chia mảng trở lại thành hàng.

E...⎇﹪κ²⮌ιι

Đảo ngược hàng thay thế.

I...

Chuyển đổi từng mục nhập thành chuỗi và đầu ra ở định dạng đầu ra mặc định là một số trên mỗi dòng với các hàng cách nhau hai lần. (Định dạng bằng dấu phân cách sẽ tiêu tốn chiều dài của dải phân cách.)



1

Japt , 28 byte

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

Thử nó

Câu trả lời của cảng Arnauld . Thách thức lớn nhất là tạo ra một chức năng có thể tái sử dụng. Đặc biệt, có một chức năng trợ giúp để đảo ngược mọi hàng khác. Cách tiếp cận mà tôi đang thực hiện là thực hiện một cuộc gọi đệ quy và tùy thuộc vào việc một biến có được đặt hay không.

Phiên dịch mã hóa:

// 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 byte

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

Hãy thử trực tuyến!

Đã sử dụng đảo ngược hàng lẻ từ câu trả lời của Jonathan Allan .

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 # (Trình biên dịch tương tác Visual C #) , 141 byte

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];}

Hãy thử trực tuyến!

Tổng cộng -5 byte nhờ @someone!

Hàm ẩn danh thực hiện sửa đổi tại chỗ cho ma trận đầu vào.

Một vòng lặp duy nhất lặp lại trên các ô. Bạn có thể quét từ trên xuống dưới và từ trái sang phải bằng các công thức sau:

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

Trường hợp ilà một bộ đếm vòng lặp và wlà số lượng cột. Điều này thay đổi một chút khi quét trong một mô hình con rắn.

  • row=i/w
  • col=i%w (Hàng 0, 2, 4, v.v.)
  • col=w-i%w-1 (Hàng thứ 1, 3, 5, v.v.)

Một điều cần lưu ý là %trong C # không chuyển đổi thành giá trị dương như ở một số ngôn ngữ khác. Một vài byte bổ sung là cần thiết để giải thích cho điều này.

// 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
    ];
}

Bạn có thể lưu 3 byte bằng cách hợp nhất các khai báo với dynamic; bình luận quá l. Hãy thử trực tuyến!
đại từ của tôi là monicareinstate

Nice :) Tuyên bố đó cũng có thể được chuyển vào vòng lặp. Tôi có xu hướng sử dụng varđể chơi golf mà không cho phép bạn khai báo danh sách các biến. Có lẽ tại sao tôi bỏ lỡ điều này. Nắm bắt tốt!
dana

Loại bỏ yhoàn toàn để tiết kiệm 2 byte: Hãy thử trực tuyến!
đại từ của tôi là monicareinstate

@someone - cảm ơn!
dana

TIO 135 với đầu vào mảng 1d và chiều rộng.
đại từ của tôi là monicareinstate
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.