Gire todas as linhas e colunas de uma matriz

15

O desafio

Dada uma n x nmatriz de números inteiros comn >= 2

1 2
3 4

e uma lista de números inteiros com exatamente 2nelementos

[1,2, -3, -1]

produzir a matriz girada. Essa matriz é construída da seguinte maneira:

  • Pegue o primeiro número inteiro na lista e gire a primeira linha para a direita com esse valor.
  • Pegue o próximo número inteiro e gire a primeira coluna para baixo por esse valor.
  • Pegue o próximo número inteiro e gire a segunda linha para a direita por esse valor, etc. até você girar todas as linhas e colunas da matriz uma vez.

A lista pode conter números inteiros negativos, o que significa que você desloca a linha / coluna para a esquerda / para cima em vez de para a direita / para baixo. Se o número inteiro for zero, não gire a linha / coluna.

Exemplo usando a entrada acima

Elemento de lista Matriz Explicação
-------------------------------------------------- ----------
1 2 1 Gire a 1ª linha para a direita 1
                   3 4

2 2 1 Gire a 1ª coluna para baixo 2
                   3 4

-3 2 1 Gire a 2ª linha deixada por 3
                   4 3

-1 2 3 Gire a 2ª coluna para cima 1
                   4 1

Regras

  • Você pode escolher o formato de entrada mais conveniente. Apenas deixe claro qual deles você usa.
  • Função ou programa completo permitido.
  • Regras padrão para entrada / saída.
  • Aplicam-se brechas padrão .
  • Isso é , portanto, a menor contagem de bytes vence. O desempatador é uma inscrição anterior.

Casos de teste

O formato de entrada aqui é uma lista de listas para a matriz e uma lista normal para os números inteiros.

[[1,2], [3,4]], [1,2, -3, -1] -> [[2,3], [4,1]]
[[1,2], [3,4]], [1,1,1,1] -> [[3,2], [4,1]]
[[1,2], [3,4]], [0,0,0,0] -> [[1,2], [3,4]]
[[1,2, -3], [- 4,5,6], [7, -8,0]], [1, -2,0, -1,3,4] -> [[7, 5,0], [- 3, -8,2], [- 4,1,6]]
[[1,2, -3], [- 4,5,6], [7, -8,0]], [3,12, -3,0, -6, -3] -> [[1 , 2, -3], [- 4,5,6], [7, -8,0]]

Feliz codificação!

Denker
fonte
o mapcar deve ajudar ...
msh210

Respostas:

6

CJam, 13 bytes

{{a.m>1m<z}/}

Um bloco sem nome (função) que pega a matriz e a lista no topo da pilha (nessa ordem) e deixa a nova matriz em seu lugar.

Execute todos os casos de teste.

Mesma idéia, mesmo número de bytes, diferentes implementações:

{{\(@m>a+z}/}
{{(Im>a+z}fI}
{{:\Im>]z}fI}

Explicação

Idealmente, queremos tratar cada instrução da lista da mesma forma e usá-la para girar a primeira linha da matriz. Isso pode ser feito facilmente, transformando a matriz após cada instrução um pouco e garantindo que todas essas transformações extras sejam canceladas no final. Portanto, após o processamento de cada instrução, rotacionamos todas as linhas uma para cima (de modo que a próxima instrução na mesma dimensão processe a próxima linha) e depois transpomos a matriz, de modo que estamos processando as colunas a seguir. Essas transformações adicionais são ortogonais às instruções da lista e têm exatamente um período exatamente do 2nque precisamos.

Quanto ao código:

{      e# For each instruction...
  a    e#   Wrap it in a singleton array.
  .m>  e#   Combine it element-wise with the matrix to rotate right. This is
       e#   a fairly common idiom to apply a binary operation only to the first
       e#   element of an array, since element-wise operations just retain all the
       e#   unpaired elements of the longer array.
  1m<  e#   Rotate the rows one up.
  z    e#   Transpose.
}/
Martin Ender
fonte
4

APL (Dyalog Extended) , 17 15 14 13 bytes

-3 bytes por Adám

(⍉1⊖⌽`@1⍢⌽)/⌽

Experimente online!

Recebe a entrada como uma lista em que o primeiro elemento é a matriz e os elementos restantes são os valores de rotação. Se ⌽ girasse para a direita em vez de para a esquerda, isso venceria o CJam.

(⍉1⊖⌽@1 1⍢⌽)/⌽    Monadic train:
(⍉1⊖⌽@1 1⍢⌽)      Helper function to rotate and transpose once.
                        Takes args  (amount to rotate) and  (current array)
                      Function to rotate left
        1 1             2-element vector containing 1.
                        The second 1 is redundant, but saves 1 byte over (,1).
     ⌽@1 1             Function to rotate the 1st row left by ⍺.
     ⌽@1 1⍢⌽          Reverse ⍵, rotate 1st row left by ⍺, then reverse again.
                        This rotates the first row of  to the *right*.
  1                   Rotate all the rows upward,
                                                  then transpose.
(⍉1⊖⌽@1 1⍢⌽)/⌽   Fold (/) this function over the reversed input.
                     If our input is ⍵, _1, _2, ..., _2n,
                     the reversed input will be _2n, ..., _1, ⍵.
                     The / operator applies the function right to left,
                     so the  is necessary.
lirtosiast
fonte
{⍉1⊖⌽⍺⌽@(⍳1)⌽⍵}(⍉1⊖⌽@(⍳1)⍢⌽)mas você pode me explicar por @1que não funciona em vez de @(⍳1)ou @(,1)? Além disso, o OP pode permitir a entrada inversa.
Adám 11/02/19
Portanto, o dfns ', atque está por trás do estendido, @não é uma extensão compatível. No entanto, você pode usar o nativo @com o `@1qual salva um byte @1 1.
Adám 12/02/19
rodar funciona de maneira diferente em apl vs J? Estou tentando traduzir isso para J e encontrando-o muito mais detalhado ...
Jonah
2

Python 2, 96 bytes

def f(m,v):
    for i,x in enumerate(v):x%=len(m);r=m[i/2];m[i/2]=r[-x:]+r[:-x];m=zip(*m)
    return m

Testes

fretorna uma lista de tuplas. Cada linha no corpo da função é recuada com 1 caractere de tabulação.

vaultah
fonte
Um straight não return zip(*m)economizaria 5 bytes?
Denker
@ DenkerAffe: você está sugerindo substituir m=zip(*m);return mpor apenas return zip(*m)? Eu não posso fazer isso porque m=zip(*m)é uma parte do forcircuito
vaultah
Sim, esse foi o meu pensamento. Não vi isso no loop, meu mal.
Denker