Alternativamente, desplazar columnas y filas de una matriz 2D

15

Objetivo

Dada una matriz 2D de cualquier tamaño, escriba un programa o función para cambiar alternativamente las columnas y filas

Ejemplo

a b c d e
f g h i j
k l m n o

Todos los elementos en la primera columna se desplazan hacia abajo una fila, la segunda columna se desplaza hacia arriba una fila, el tercer desplazamiento hacia abajo una fila y así sucesivamente, envolviéndose cuando alcanzan el borde.

k g m i o
a l c n e
f b h d j  

Todos los elementos en la primera fila se desplazan hacia la derecha , el segundo hacia la izquierda , el tercero hacia la derecha , etc., envolviéndose cuando alcanzan el borde.

o k g m i
l c n e a
j f b h d

Seguiré la tradición de seleccionar el código de trabajo más corto como la mejor respuesta

Karan Shishoo
fuente
¿Puede la matriz ser de cualquier tamaño, o específicamente de 3x5?
Jo King el
Estaba buscando cualquier matriz 2D llena. lo siento por no mencionarlo. Agregaré una edición
Karan Shishoo
Para ser sincero, el formato incorrecto hace que la pregunta parezca una pregunta fuera de tema de un usuario SO perezoso.
user202729
(Por cierto, no acepte una respuesta demasiado pronto)
user202729
55
@kshishoo Para futuros desafíos, puede usar el Sandbox para verificar si hay duplicados y / o recopilar algunos comentarios antes de publicar en el sitio principal
Rod

Respuestas:

3

Casco , 7 bytes

‼ozṙİ_T

Pruébalo en línea!

Explicación

‼ozṙİ_T  Implicit input: a list of lists.
‼        Do this twice:
      T   Transpose,
 oz       then zip with
    İ_    the infinite list [-1,1,-1,1,-1,1,..
   ṙ      using rotation. This rotates the rows in alternating directions.
Zgarb
fuente
7

MATL , 13 bytes

,!tZy:oEq2&YS

Pruébalo en línea!

Explicación

,        % Do twice
  !      %   Transpose. Takes input implicitly the first time
  t      %   Duplicate
  Zy     %   Size. Gives a vector with numbers of rows and of columns
  :      %   Range from 1 to the first entry of the vector (number of rows)
  o      %   Parity: gives 0 or 1 for eacn entry
  Eq     %   Times 2, minus 1: transforms 0 into -1
  2      %   Push 2
  &YS    %   Circularly shift along the second dimension. This shifts the
         %   first row by 1 (that is, to the right), the second by -1 (to
         %   the left), etc.
         % End (implicit). Display (implicit)
Luis Mendo
fuente
6

J , 26, 21 19 bytes

-5 bytes gracias a millas

(|."_1~_1^#\)@|:^:2

Explicación:

^:2 - repita dos veces lo siguiente:

@|: - transponer y

#\ - encuentra la longitud de los prefijos (1, 2, 3 ... filas)

_1^ - elevar -1 a las potencias anteriores, creando una lista de -1 -1 -1 1 alterna ...

|."_1~ - gire cada fila de la matriz de entrada con desplazamiento de la lista anterior

Pruébalo en línea!

Versión original:

(($_1 1"0)@#|."0 1])@|:^:2

Cómo funciona

^:2 - repita dos veces lo siguiente:

|: - transponer y

|."0 1] - Gire cada fila de la matriz de entrada, compensaciones en la lista:

@# - el número de filas en la matriz

($_1 1"0) - alternativo _1 1 (3 -> _1 1 _1)

Pruébalo en línea!

Galen Ivanov
fuente
1
Puede generar el _1 1..uso (|."_1~_1^2|#\)@|:^:2también
millas
@miles ¡Gracias, es un gran código!
Galen Ivanov
@miles, de hecho, no necesito el 2|papel
Galen Ivanov
1
Sí, en realidad no, son otros 2 bytes guardados.
millas
2

APL + WIN, 30 bytes

Solicita la entrada de pantalla de una matriz 2D

((↑⍴m)⍴¯1 1)⌽((1↓⍴m)⍴¯1 1)⊖m←⎕
Graham
fuente
2

APL (Dyalog Unicode) , 26 bytes

{(¯1 1⍴⍨≢⍵)⌽(¯1 1⍴⍨≢⍉⍵)⊖⍵}

Pruébalo en línea!

Prefijo Dfn.

¿Cómo?

{(¯1 1⍴⍨≢⍵)⌽(¯1 1⍴⍨≢⍉⍵)⊖⍵}⍝ Main function, prefix. Input matrix is ⍵.
                        ⊖⍵}⍝ Rotate the columns of  according to the left arg:
            (       ⍉⍵)     Transpose  (makes a 3x5 matrix become 5x3)
                           Tally (yields the number of rows of the matrix)
                           Swap arguments of the following fn/op
                           Shape
             ¯1 1           This vector. This yields a vector of ¯1 1 with size = number of columns of ⍵.
                           Rotate the rows of  according to the left arg:
{(¯1 1⍴⍨≢⍵)                 Does the same as the preceding expression, without transposing ⍵.
J. Sallé
fuente
2

JavaScript (ES6), 94 91 bytes

a=>(g=a=>a[0].map((_,i)=>(b=a.map(a=>a[i]),i%2?[...b.slice(1),b[0]]:[b.pop(),...b])))(g(a))

Probablemente haya una forma más golfista de hacer la rotación ...

Neil
fuente
2

Pyth, 15 bytes

L.e.>b^_1k.Tbyy

Pruébalo en línea

Explicación

L.e.>b^_1k.Tbyy
L           b      Define a function on a list...
          .T       ... which transposes it...
 .e.>b^_1k         ... and rotates each row alternating left and right.
             yyQ   Apply twice to the (implicit) input array.

fuente
2

q / kdb + , 32 bytes

Solución:

{rotate'[#:[x+:]#-1 1](+)x}/[2;]

Ejemplo:

q)3 5#.Q.a / reshape "a..o" into 3 row, 5 column grid
"abcde"
"fghij"
"klmno"
q){rotate'[#:[(+)x]#-1 1](+)x}/[2;]3 5#.Q.a
"okgmi"
"lcnea"
"jfbhd"

Explicación:

Voltee la cuadrícula para aplicar rotación a las columnas , la segunda iteración voltea una vez más, por lo tanto, la rotación se aplica a las filas en la segunda pasada.

La rotación se basa en la lista -1 1 -1 1..de la longitud de la fila / columna que se rota.

Se han extraído unos 9 bytes de esta versión más fácil de leer.

{rotate'[count[flip x]#-1 1;flip x]}/[2;] / ungolfed solution
{                                  }/[2;] / perform lambda 2 times
 rotate'[                  ;      ]       / perform rotate on each-both
                            flip x        / flip x<->y of grid
                      #-1 1               / take from list -1 1
         count[flip x]                    / the length of the flipped grid
callejero
fuente
2

JavaScript (ES6),  116  76 bytes

m=>(g=m=>m[0].map((_,x)=>m.map(_=>m[y++%h][x],h=m.length,y=x&1||h-1)))(g(m))

Pruébalo en línea!

Comentado

m => (                 // m[] = input matrix
  g = m =>             // g is the main helper function taking a matrix m[]
    m[0].map((_, x) => // for each column at position x in m[]:
      m.map(_ =>       //   for each row of m[]:
        m[y++ % h][x], //     yield the x-th value of the row (y mod h) and increment y
        h = m.length,  //     h = number of rows
        y = x & 1      //     start with y = 1 if x is odd,
            || h - 1   //     or h - 1 if x is even
      )                //   end of inner map()
  )                    // end of outer map()
)(g(m))                // invoke g twice on the input matrix
Arnauld
fuente
1

Limpio , 93 bytes

import StdEnv,StdLib
k=[0,1:k]
^l=[[[last a:init a],tl a++[hd a]]!!b\\a<-transpose l&b<-k]

^o^

Como una función parcial literal, eso parece una cara.

Pruébalo en línea!

Οurous
fuente
0

05AB1E , 14 bytes

2FøvyNÉiÀëÁ}})

Pruébalo en línea!

Explicación

2F               # 2 times do:
  ø              # zip
   vy            # for each row(y), index(N) do:
     NÉiÀ        # if N is odd, rotate left
         ëÁ      # else rotate right
           }}    # end if and inner loop
             )   # wrap in list
Emigna
fuente
0

NARS APL, 36 bytes, 18 caracteres

c←b∘b←{⍵⌽⍨-×-\⍳≢⍵}∘⍉

Este {⍵⌽⍨- × - \ ⍳≢⍵} rotaría cada fila del argumento de la matriz siguiendo el vector -1 1 -1 1, etc. (que tiene su longitud del vector la longitud de las filas de la matriz del argumento). Prueba:

  ⎕←a←3 5⍴⎕A
ABCDE
FGHIJ
KLMNO
  ⎕←c a
OKGMI
LCNEA
JFBHD
RosLuP
fuente
Continuemos esta discusión en el chat .
Erik the Outgolfer
0

bash y cols., 84

Solución de shell no competitiva.

Esto se basa en una función que alterna la dirección de rotación de las filas. El mismo procedimiento realizado en la matriz transpuesta rotará las columnas. Por ejemplo transpose | rotate | transpose | rotate.

La rotación alterna se puede hacer en matrices de un solo carácter con sedesto:

sed -E 's/(.*) (.)$/\2 \1/; n; s/^(.) (.*)/\2 \1/'

La transposición se puede hacer con rso datamash:

rs -g1 -T
datamash -t' ' transpose

Tomados en conjunto:

r() { sed -E 's/(.*) (.)$/\2 \1/; n; s/^(.) (.*)/\2 \1/'; }
t() { rs -g1 -T; }
<f t | r | t | r

Salida:

o k g m i
l c n e a
j f b h d
Thor
fuente