蛇のようなスリザー


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

回答:


7

ゼリー、10 バイト

UÐeẎṙṁ⁸UÐe

左側のマリックスと右側の回転整数を受け入れるダイアディックリンク(正/負の逆の意味を使用)

オンラインでお試しください!

どうやって?

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

R121の 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現在の要素の行を使用してi、カラム、j...

設定します sr+iしてkまで(j+s//w)%hk現在の要素にアクセスする元の行です。

右から奇数のインデックス付き行に簡単にアクセスするために、要素にアクセスする前にそのような行を反転します(withで[:n**k])。これは、対象の要素がにあることを意味しs%wます。


3

J41 30 21バイト

ヨナのおかげで-11バイト!

FrownyFrogとngnのおかげで-9バイト!

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

オンラインでお試しください!

逆転 +/-


1
30のバイトは、+/-が逆になっていないが、それでも、ヘルパーを使用しています$@]t@$(|.,@(t=.#\,`(|.@,)/.]))オンラインをお試しください!
ヨナ

修正:+/-まだ逆です。
ヨナ

@ジョナ今、それはJです!あなたが最近、交互の反転で同じトリックを適用したのを見たことを覚えていますが、どうやらそれを忘れているようです。ありがとうございました!しよう&.としたとき、私は常に左の引数を失っていたので、私はあきらめました。
ガレンイワノフ

1
21バイト、thx @ngn
FrownyFrog

@FrownyFrogうわー、初期サイズの半分になりました。バカな気がする...ありがとう!
ガレンイワノフ

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つの数字をダブルスペースで挿入したものです。(セパレーターでフォーマットすると、セパレーターの長さがかかります。)



1

Japt、28バイト

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

それを試してみてください

アーナルドの答え。最大の課題は、再利用可能な関数を作成することでした。特に、1行おきに反転するヘルパー関数があります。私が取っているアプローチは、再帰呼び出しを行い、変数が設定されているかどうかに依存しています。

Transpiled 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

C#(Visual C#Interactive Compiler)、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

where iはループカウンターでw、列の数です。これは、蛇パターンでスキャンする場合はわずかに異なります。

  • row=i/w
  • col=i%w (0、2、4などの行)
  • col=w-i%w-1 (1行目、3行目、5行目など)

もう1つ注意すべき点は%、C#のin は他の言語のように正の値に変換されないことです。これを説明するには、2、3バイト余分に必要です。

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

宣言をdynamic; とマージすることにより、3バイトを節約できます。コメントもl。オンラインでお試しください!
私の代名詞は

ニース:)その宣言もループに移動できます。私はvar、変数のリストを宣言させないゴルフに使用する傾向があります。おそらく私がこれを逃した理由。良いキャッチ!
ダナ

y完全に取り除いて2バイト節約:オンラインで試してみてください!
私の代名詞は、

@誰か-ありがとう!
ダナ

1D配列および幅入力を備えたTIO 135
私の代名詞は、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.