Slither Like a Snake

21

Pomysł

Robiliśmy już spirale macierzy, pełne obroty, a nawet obroty po przekątnej , ale nie, o ile potrafię, rotacje węża !

Co to jest obrót węża?

Wyobraź sobie rzędy matrycy wężące się w przód iw tył, z dzielnikami między nimi jak dzielniki długiej kolejki:

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

Teraz wyobraź sobie, że obracasz te elementy o 2. Każdy przedmiot przesuwa się, podobnie jak ludzie poruszający się w linii, a przedmioty na końcu wysypują się i wracają do początku:

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

Jeśli liczba wierszy jest nieparzysta, wyjdzie ona z prawej strony, ale nadal będzie zawijać się na początek. Na przykład, oto 3 obrót:

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

Negatywny obrót zabierze Cię do tyłu. Oto obrót -2:

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

Wyzwanie

Twoja funkcja lub program przyjmie 2 dane wejściowe, w dowolnym dogodnym formacie:

  • Matryca
  • Liczba całkowita (dodatnia lub ujemna) wskazująca, ile miejsc ją obrócić.

Zwróci:

  • Obrócona matryca

Uwagi:

  • Kod golfa. Wygrywa najmniej bajtów.
  • Matryce nie muszą być kwadratowe, ale będą zawierać co najmniej 2 wiersze i 2 kolumny
  • Dodatnie liczby całkowite będą obracać wiersz 1 w prawo
  • Ujemne liczby całkowite będą obracać wiersz 1 w lewo
  • W razie potrzeby możesz odwrócić znaczenie dodatnich / ujemnych liczb rotacji
  • Liczba rotacji może być większa niż liczba elementów. W takim przypadku zostanie zawinięty. Oznacza to, że będzie to równoważne liczbie modułów.
  • Macierz będzie zawierać tylko liczby całkowite, ale może zawierać dowolne liczby całkowite, w tym powtórzenia

Przypadki testowe

Format:

  • Matryca
  • Numer obrotu
  • Oczekiwana wartość zwrotu

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
Jonasz
źródło
4
Odwrotne znaczenie +/- jest w porządku. Myślę, że wejście powinno pozostać w lewym górnym rogu.
Jonasz
7
To zdecydowanie potrzebuje odpowiedzi w Pythonie.
640 KB

Odpowiedzi:

7

Galaretka , 10 bajtów

UÐeẎṙṁ⁸UÐe

Dyadyczny link akceptujący znak po lewej stronie i liczbę całkowitą obrotu po prawej stronie (używa odwrotnego znaczenia dodatniego / ujemnego)

Wypróbuj online!

W jaki sposób?

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
Jonathan Allan
źródło
6

R , 121 110 101 bajtów

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

Wypróbuj online!

Przewodnik

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
}
Kirill L.
źródło
3

Python 3.8 (wersja wstępnaSSSse) , 119 bajtów

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

Akceptacja nienazwanej funkcji, matrix, rotationktóra daje nową macierz.
Używa przeciwnego znaku obrotu.

Wypróbuj online!

W jaki sposób?

Ustawiamy n=-1z góry, aby zaoszczędzić na nawiasach później i przyjmujemy macierz jakom a obrót jakor .

Nowa matryca ma takie same wymiary jak m- o szerokości w( w:=len(m[0])) i wysokości h(h:=len(m) ).

Każdy inny wiersz tej macierzy jest odwrócony ([::n**j] ).

Wartości są wyszukiwane poprzez obliczenie ich wiersza i kolumny w oryginale, mprzy użyciu bieżącego wiersza elementów ii kolumny,j ...

Ustawiliśmy sna r+ii kdo (j+s//w)%h.kto wiersz oryginału, do którego dostęp ma nasz obecny element.

Aby łatwo uzyskać dostęp do nieparzystych indeksowanych wierszy z prawej strony, odwracamy takie wiersze przed uzyskaniem dostępu do ich elementów (z [:n**k]), oznacza to, że element zainteresowania znajduje się w s%w.

Jonathan Allan
źródło
3

J , 41 30 21 bajtów

-11 bajtów dzięki Jonaszowi!

-9 bajtów dzięki FrownyFrog & ngn!

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

Wypróbuj online!

Wywrócony +/-

Galen Iwanow
źródło
1
30 bajtów, +/- nie jest odwrócone, ale nadal używa pomocnika: $@]t@$(|.,@(t=.#\,`(|.@,)/.]))( Wypróbuj online! )
Jonah
korekta: +/- wciąż odwrócone.
Jonasz
@Jonah Teraz to J! Pamiętam, jak ostatnio stosowałeś tę samą sztuczkę z naprzemiennym odwracaniem, ale najwyraźniej o tym zapomniałeś. Dziękuję Ci! Próbując &.cały czas traciłem lewy argument, dlatego się poddałem.
Galen Iwanow
1
21 bajtów , dzięki @ngn
FrownyFrog
@FrownyFrog Wow, to teraz połowa początkowego rozmiaru. Czuję się głupio ... Dzięki!
Galen Iwanow
2

JavaScript (Node.js) , 102 bajty

Pobiera dane wejściowe jako (matrix)(integer). Znaczenie znaku liczby całkowitej jest odwrócone.

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

Wypróbuj online!

Funkcja pomocnika

sol

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

Główna funkcja

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
Arnauld
źródło
2

05AB1E , 16 bajtów

εNFR]˜²._¹gäεNFR

Wypróbuj online!

Dzięki Emigna za -5. Niestety nie widzę, jak grać w golfa w zbędną część. :(

Erik the Outgolfer
źródło
1

Węgiel drzewny , 36 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

Eθ⎇﹪κ²⮌ιι

Odwróć alternatywne rzędy danych wejściowych.

F...Fι⊞υκ

Spłaszcz macierz.

Eυ§υ⁻κη

Obróć spłaszczony układ.

⪪...L§θ⁰

Podziel tablicę z powrotem na rzędy.

E...⎇﹪κ²⮌ιι

Odwróć alternatywne rzędy.

I...

Konwertuj każdy wpis na ciąg i dane wyjściowe w domyślnym formacie wyjściowym, który jest jedną liczbą w wierszu z wierszami podwójnie rozmieszczonymi. (Formatowanie za pomocą separatora kosztowałoby długość separatora).

Neil
źródło
1

Pyth, 20 bajtów

L.e_W%k2bbyclQ.>syQE

Wypróbuj online tutaj .

Sok
źródło
1

Japt , 28 bajtów

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

Spróbuj

Odpowiedź Portu Arnaulda . Największym wyzwaniem było stworzenie funkcji wielokrotnego użytku. W szczególności istnieje funkcja pomocnicza do odwracania co drugi wiersz. Podejście, które podejmuję, polega na wykonaniu połączenia rekurencyjnego i zależy od tego, czy zmienna jest ustawiona.

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)
dana
źródło
1

Python 3 , 94 bajty

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

Wypróbuj online!

Wykorzystałem odwrócenie nieparzystego rzędu z odpowiedzi Jonathana Allana .

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_[]
attinat
źródło
1

C # (interaktywny kompilator Visual C #) , 141 bajtów

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

Wypróbuj online!

Łącznie -5 bajtów dzięki @someone!

Anonimowa funkcja, która dokonuje modyfikacji w miejscu macierzy wejściowej.

Pojedyncza pętla przechodzi przez komórki. Możesz skanować od góry do dołu i od lewej do prawej za pomocą następujących wzorów:

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

Gdzie ijest licznikiem pętli i wliczbą kolumn. Różni się to nieznacznie podczas skanowania we wzór węża.

  • row=i/w
  • col=i%w (0, 2, 4 itd. Rząd)
  • col=w-i%w-1 (1., 3., 5. itd.)

Inną rzeczą wartą uwagi jest to, że %w C # nie konwertuje się na wartość dodatnią, tak jak w niektórych innych językach. Potrzebne jest kilka dodatkowych bajtów, aby to uwzględnić.

// 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
    ];
}
dana
źródło
Możesz zapisać 3 bajty, łącząc deklaracje z dynamic; komentarz też l. Wypróbuj online!
mój zaimek to monicareinstate
Fajnie :) Deklarację tę można również przenieść do pętli. Zwykle używam vardo gry w golfa, co nie pozwala zadeklarować listy zmiennych. Prawdopodobnie dlatego mi tego brakowało. Dobry chwyt!
dana
Pozbądź się ycałkowicie, aby zaoszczędzić 2 bajty: Wypróbuj online!
mój zaimek to monicareinstate
@someone - dzięki!
dana
TIO 135 z tablicą 1d i wejściem szerokości.
mój zaimek to monicareinstate