Gleiten wie eine Schlange


21

Die Idee

Wir haben schon einmal Matrixspiralen gemacht und volle Rotationen und sogar diagonale Rotationen , aber soweit ich das beurteilen kann, keine Schlangenrotationen !

Was ist eine Schlangenrotation?

Stellen Sie sich die Reihen einer Matrix vor, die sich hin und her schlängeln, mit Trennlinien zwischen ihnen wie die Trennlinien einer langen Warteschlange:

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

Stellen Sie sich nun vor, Sie drehen diese Objekte um 2. Jedes Objekt rückt vor, so wie sich Personen in einer Reihe bewegen, und die Objekte am Ende werden ausgeblendet und kehren zum Anfang zurück:

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

Wenn es eine ungerade Anzahl von Zeilen gibt, wird es von rechts beendet, aber immer noch zum Anfang umgebrochen. Zum Beispiel ist hier eine 3 Drehung:

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

Eine negative Drehung führt Sie rückwärts. Hier ist eine -2 Drehung:

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

Die Herausforderung

Ihre Funktion oder Ihr Programm nimmt 2 Eingaben in einem beliebigen Format entgegen:

  • Eine Matrix
  • Eine Ganzzahl (positiv oder negativ), die angibt, an wie vielen Stellen gedreht werden soll.

Es wird zurückkehren:

  • Die gedrehte Matrix

Anmerkungen:

  • Code Golf. Wenigste Bytes gewinnt.
  • Matrizen müssen nicht quadratisch sein, sondern enthalten mindestens 2 Zeilen und 2 Spalten
  • Positive Ganzzahlen drehen Zeile 1 nach rechts
  • Negative Ganzzahlen drehen Zeile 1 nach links
  • Sie können die Bedeutung von positiven / negativen Rotationsnummern umkehren, falls dies zweckmäßig ist
  • Die Rotationsnummer kann größer sein als die Anzahl der Elemente. In diesem Fall wird es gewickelt. Das heißt, es entspricht der Anzahl Modulo der Anzahl der Elemente.
  • Die Matrix enthält nur Ganzzahlen, kann jedoch beliebige Ganzzahlen enthalten, einschließlich Wiederholungen

Testfälle

Format:

  • Matrix
  • Umdrehungszahl
  • Erwarteter Rückgabewert

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
Die Umkehrung der Bedeutung von +/- ist in Ordnung. Ich denke, der Eingang sollte oben links bleiben.
Jonah

7
Dies muss auf jeden Fall in Python beantwortet werden.
640 KB,

Antworten:


7

Gelee , 10 Bytes

UÐeẎṙṁ⁸UÐe

Ein dyadischer Link, der den Marix auf der linken Seite und die Rotationszahl auf der rechten Seite akzeptiert (verwendet die umgekehrte Bedeutung von positiv / negativ)

Probieren Sie es online!

Wie?

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 Bytes

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

Probieren Sie es online!

Komplettlösung

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 Bytes

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

Eine unbenannte Funktion, matrix, rotationdie die neue Matrix akzeptiert .
Verwendet das entgegengesetzte Rotationszeichen.

Probieren Sie es online!

Wie?

Wir haben uns vorgenommen, n=-1Klammern später zu speichern und die Matrix als mund die Rotation als zu übernehmen r.

Eine neue Matrix wird mit denselben Abmessungen wie m- mit einer Breite von w( w:=len(m[0])) und einer Höhe von h( h:=len(m)) konstruiert .

Jede zweite Zeile dieser Matrix ist umgekehrt ( [::n**j]).

Die Werte werden durch Berechnen ihrer Zeile und Spalte im Original unter mVerwendung der aktuellen Elemente row,, iund column, j... nachgeschlagen.

Wir setzen sauf r+iund kzu (j+s//w)%h. kist die Zeile des Originals, auf die für unser aktuelles Element zugegriffen werden soll.

Um einfach von rechts auf ungerade indizierte Zeilen zuzugreifen, kehren wir diese Zeilen um, bevor wir auf ihre Elemente (mit [:n**k]) zugreifen. Dies bedeutet, dass sich das Element von Interesse auf befindet s%w.


3

J , 41 30 21 Bytes

-11 Bytes danke an Jonah!

-9 Bytes dank FrownyFrog & ngn!

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

Probieren Sie es online!

Rückgängig gemacht +/-


1
30 Bytes, +/- nicht rückgängig gemacht, aber es wird immer noch ein Hilfsprogramm verwendet: $@]t@$(|.,@(t=.#\,`(|.@,)/.]))( Online ausprobieren! )
Jonah,

Korrektur: +/- noch rückgängig gemacht.
Jonah

@Jonah Das ist J! Ich erinnere mich, dass Sie vor kurzem denselben Trick bei der abwechselnden Umkehrung angewendet haben, aber anscheinend vergessen haben. Vielen Dank! Als &.ich es versuchte, verlor ich die ganze Zeit den linken Streit, deshalb gab ich auf.
Galen Ivanov

1
21 bytes , thx @ngn
FrownyFrog

@FrownyFrog Wow, es ist jetzt die Hälfte der ursprünglichen Größe. Ich fühle mich dumm ... Danke!
Galen Ivanov

2

JavaScript (Node.js) , 102 Byte

Übernimmt die Eingabe als (matrix)(integer). Die Bedeutung des Vorzeichens der ganzen Zahl ist invertiert.

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

Probieren Sie es online!

Hilfsfunktion

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

Hauptfunktion

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

Kohle , 36 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

Eθ⎇﹪κ²⮌ιι

Alternierende Zeilen der Eingabe umkehren.

F...Fι⊞υκ

Reduzieren Sie das Array.

Eυ§υ⁻κη

Drehen Sie das abgeflachte Array.

⪪...L§θ⁰

Teilen Sie das Array wieder in Zeilen auf.

E...⎇﹪κ²⮌ιι

Wechselnde Zeilen umkehren.

I...

Konvertieren Sie jeden Eintrag in eine Zeichenfolge und geben Sie ihn im Standardausgabeformat aus. Dabei handelt es sich um eine Zahl pro Zeile mit Zeilen in doppelten Abständen. (Das Formatieren mit einem Trennzeichen würde die Länge des Trennzeichens kosten.)



1

Japt , 28 Bytes

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

Versuch es

Antwort von Port of Arnauld . Die größte Herausforderung bestand darin, eine wiederverwendbare Funktion zu erstellen. Insbesondere gibt es eine Hilfsfunktion, um jede zweite Zeile umzukehren. Der Ansatz, den ich verwende, besteht darin, einen rekursiven Aufruf durchzuführen und davon abzuhängen, ob eine Variable festgelegt ist.

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

Python 3 , 94 Bytes

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

Probieren Sie es online!

Verwendete die ungerade Zeilenumkehrung aus Jonathan Allans Antwort .

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 # Interactive Compiler) , 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];}

Probieren Sie es online!

-5 Bytes insgesamt dank @someone!

Anonyme Funktion, die eine direkte Änderung der Eingabematrix vornimmt.

Eine einzelne Schleife durchläuft die Zellen. Sie können mit den folgenden Formeln von oben nach unten und von links nach rechts scannen:

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

Wo iist ein Schleifenzähler und wist die Anzahl der Spalten. Dies variiert geringfügig beim Scannen in einem Schlangenmuster.

  • row=i/w
  • col=i%w (0., 2., 4. usw. Reihe)
  • col=w-i%w-1 (1., 3., 5. usw. Reihe)

Eine weitere zu beachtende Sache ist, dass das %in C # nicht in einen positiven Wert konvertiert wird, wie dies in einigen anderen Sprachen der Fall ist. Ein paar zusätzliche Bytes sind erforderlich, um dies zu berücksichtigen.

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

Sie können 3 Byte sparen, indem Sie Deklarationen mit dynamic; Kommentar auch l. Probieren Sie es online!
Mein Pronomen ist monicareinstate

Nett :) Diese Deklaration kann auch in die Schleife verschoben werden. Ich neige dazu, varGolf zu spielen, bei dem Sie keine Liste von Variablen deklarieren können. Wahrscheinlich, warum ich das verpasst habe. Guter Fang!
Dana

yGanz loswerden , um 2 Bytes zu sparen: Online ausprobieren!
Mein Pronomen ist monicareinstate

@jemand - danke!
Dana

TIO 135 mit 1d-Array- und Breiteneingang.
Mein Pronomen ist monicareinstate
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.