Soma de rotação


26

Pegue uma matriz quadrada contendo números inteiros positivos como entrada e calcule a "soma rotacionada" da matriz.

Soma girada:

Pegue a soma da matriz original e a mesma matriz girou 90, 180 e 270 graus.

Suponha que a matriz seja:

 2    5    8
 3   12    8
 6    6   10

a soma girada será:

2    5    8     8    8   10    10    6    6     6    3    2
3   12    8  +  5   12    6  +  8   12    3  +  6   12    5  = 
6    6   10     2    3    6     8    5    2    10    8    8   

26   22   26
22   48   22
26   22   26

Casos de teste:

Entrada e saída separadas por traços, diferentes casos de teste separados por uma nova linha. Casos de teste em formatos mais convenientes podem ser encontrados aqui .

1
-------------
4

1 3
2 4
-------------
10   10 
10   10    

14    6    7   14
 6   12   13   13
 6    2    3   10
 5    1   12   12
-------------
45   37   24   45
24   30   30   37
37   30   30   24
45   24   37   45    

14    2    5   10    2
18    9   12    1    9
 3    1    5   11   14
13   20    7   19   12
 2    1    9    5    6
-------------
24   29   31   41   24
41   49   31   49   29
31   31   20   31   31
29   49   31   49   41
24   41   31   29   24

O código mais curto em bytes em cada idioma vence. As explicações são altamente encorajadas!

Respostas:


9

Python 2 , 78 bytes

Agradeço a Dennis por jogar dois bytes fora da minha abordagem recursiva anterior.

f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)

Experimente online! ou Veja uma suíte de testes.


Python 2 , 80 81 83 85 bytes (não recursivo)

Recebe entrada como uma lista de singleton .

l=input()
exec"l+=zip(*l[-1][::-1]),;"*3
print[map(sum,zip(*d))for d in zip(*l)]

Experimente online!

Funcionalidade de código

Como isso é bastante demorado para analisá-lo como um todo, vamos dar uma olhada peça por peça:

f = lambda *l:                # This defines a lambda-function that can accept any number
                              # of arguments (the matrix) using starred expressions.
l[3:] and ...X... or ...Y...  # If l[3:] is truthy (that is, the length of the list is
                              # higher than 3), return X, otherwise Y.

[map(sum,zip(*d))for d in zip(*l)]     # The first expression, X.
[                                ]     # Start a list comprehension, that:
                 for d in              # ... Iterates using a variable d on:
                          zip(*l)      # ... The "input", l, transposed.
         zip(*d)                       # ... And for each d, transpose it...
 map(sum,       )                      # ... And compute the sum of its rows.
                                       # The last two steps sum the columns of d.

f(zip(*l[0][::-1]),*l)     # The second expression, Y. This is where the magic happens.
f(                   )     # Call the function, f with the following arguments:
  zip(*          )         # ... The transpose of:
       l[0][::-1]          # ...... The first element of l (the first arg.), reversed.
                  ,        # And:
                   *l      # ... l splatted. Basically turns each element of l
                           # into a separate argument to the function.

E para o segundo programa:

l=input()                                # Take input and assign it to a variable l.
                                         # Note that input is taken as a singleton list.

exec"l+=zip(*l[-1][::-1]),;"*3           # Part 1. Create the list of rotations.
exec"                     ;"*3           # Execute (Do) the following 3 times:
     l+=                 ,               # ... Append to l the singleton tuple:
        zip(*           )                # ...... The transpose of:
             l[-1][::-1]                 # ......... The last element of l, reversed.

print[map(sum,zip(*d))for d in zip(*l)]  # Part 2. Generate the matrix of sums.
print                                    # Output the result of this expression:
     [                for d in        ]  # Create a list comprehension, that iterates
                                         # with a variable called "d" over:
                               zip(*l)   # ... The transpose of l.
      map(sum,       )                   # ... And computes the sum:
              zip(*d)                    # ... Of each row in d's transpose.
                                         # The last 2 steps generate the column sums.

TL; DR: Gere a lista de matrizes necessárias girando a entrada 3 vezes por 90 graus e coletando os resultados. Em seguida, obtenha as somas das colunas de cada matriz na transposição do resultado.


f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)salva dois bytes com a entrada "normal". Experimente online!
Dennis

@ Dennis Obrigado! Eu pensei que lambda*lnão era possível no Python 2 por algum motivo.
Xcoder

Você não pode fazer x,*y=1,2,3no Python 2.7 ou [*x]no Python 3.4, mas expressões com estrela podem ser usadas para argumentos de função, mesmo no Python 1.6. Experimente online!
Dennis

8

Oitava , 29 bytes

@(x)(y=x+rot90(x))+rot90(y,2)

Experimente online!

Explicação

Isso adiciona a matriz de entrada com uma versão rotacionada em 90 graus de si mesma. O resultado é então adicionado com uma versão girada em 180 graus de si mesmo.


5

Limpo , 110 bytes

import StdEnv,StdLib
r=reverse
t=transpose
z=zipWith(+)
$m=[z(z(r b)a)(z(r c)d)\\a<-m&b<-r m&c<-t m&d<-r(t m)]

Experimente online!

Das matrizes:

  • X = transpose(reverse M): Rotação de 90 graus
  • Y = reverse(map reverse M): Rotação de 180 graus
  • Z = reverse(transpose M): Rotação de 270 graus

Isso fecha o operador de adição sobre Me X, assim como Ye Z, e sobre os resultados.



5

Julia 0.6 , 29 bytes

x*y=rotr90(y,x)
!x=x+1x+2x+3x

Experimente online!

Não consegui ficar abaixo da solução do LukeS

Mas, ao tentar, eu pensei nisso, o que eu acho meio fofo.

Primeiro, redefinimos a multiplicação para ser a operação de rotação, onde a primeira vez é o número de vezes para girar. Então, como julia multipes por justaposição, então: 1xtorna - se rotr90(x,1)e 3xtorna - se rotr90(x,3)etc.

Então escrevemos a soma.


5

Julia 0.6 , 28 24 bytes

~A=sum(rotr90.([A],0:3))

Experimente online!

~A=sum(rotr90.([A],0:3)) #
~                        # redefine unary operator ~
 A                       # function argument
               [A]       # put input matrix A into a list with one element
                   0:3   # integer range from 0 to 3
       rotr90.(   ,   )  # apply function rotr90 elementwise, expand singleton dimensions
       rotr90.([A],0:3)  # yields list of rotated matrices:
                         # [rotr90(A,0), rotr90(A,1), rotr90(A,2), rotr90(A,3)]
  sum(                )  # sum

1
Vale a pena notar que, para fazer o [1]exemplo, deve-se fazer, ~reshape([1], (1,1))porque é assim que uma matriz 1x1 é declarada em julia 0.6.
Lyndon White


4

MATL , 9 bytes

i3:"G@X!+

Experimente no MATL Online

Explicação

i       # Explicitly grab the input matrix
3:"     # Loop through the values [1, 2, 3], and for each value, N:
  G     # Grab the input again
  @X!   # Rotate the value by 90 degrees N times
  +     # Add it to the previous value on the stack
        # Implicitly end the for loop and display the resulting matrix

4

Oitava , 33 bytes

@(a)a+(r=@rot90)(a)+r(a,2)+r(a,3)

Experimente online!

Explicação:

(r=@rot90)de uma maneira embutida de criar um identificador de função rusado para girar a matriz 90 graus. Se kfor dado um segundo argumento, rele girará os k*90graus da matriz . Portanto, isso é equivalente ao pseudo-código:

a + rot90(a) + rot180(a) + rot270(a)



3

MATL , 7 bytes

,t@QX!+

Experimente no MATL Online!

Explicação

Porto da minha resposta Oitava.

,        % Do twice
  t      %   Duplicate. Takes input (implicit) the first time
  @Q     %   Push 1 in the first iteration, and 2 in the second
  X!     %   Rotate by that many 90-degree steps
  +      %   Add
         % End (implicit). Display (implicit)

3

R , 69 64 bytes

function(x,a=function(y)apply(y,1,rev))x+a(x)+a(a(x))+a(a(a(x)))

Experimente online!


Tentativa número três no codegolf. De 69 a 64 bytes, graças a Giuseppe!


Mover apara um argumento de função economizará bytes, permitindo que você se livre do {}corpo da função. Além disso, portar a abordagem Octave de Luis Mendo pode economizar alguns bytes? Finalmente, não tenho 100% de certeza, mas é t(apply(x,2,rev))equivalente a apply(x,1,rev)?
Giuseppe

Obrigado, consegui melhorar com as dicas 1 e 3. Eu não conseguiram salvar bytes, adicionando um argumento npara a()repetir a operação embora.
Florian

1
Eu quis dizer algo parecido com isto
Giuseppe



2

JavaScript (ES6), 77 bytes

a=>a.map((b,i)=>b.map((c,j)=>c+a[j][c=l+~i]+a[c][c=l+~j]+a[c][i]),l=a.length)

2

Geléia , 7 bytes

ṚZ$3СS

Experimente online!

Guardado 1 byte graças a Erik the Outgolfer (também graças a uma sugestão para corrigir um bug).

Quão?

ṚZ $ 3СS || Programa completo (monádico).

   3С || Faça isso 3 vezes e colete resultados em uma lista
  $ || -> Aplique os dois últimos links como mônada
Ṛ || –––> Reverso,
 Z || –––> Transpor.
      S || Somatório.


2

APL (Dyalog Classic) , 17 bytes

{⍵+⌽∘⍉⍵+⌽∘⊖⍵+⍉⌽⍵}

Experimente online!

APL NARS 34bytes 21 17 caracteres

{⍵+⌽∘⍉⍵+⌽∘⊖⍵+⍉⌽⍵}

-2 caracteres graças a ngn

-2 caracteres porque o operador composto ∘ parece ter precedência em +

parece ⌽⍉a gira a de 90 °, ⌽⊖a gira de 180 °, rota gira de 270 ° como ⍉⌽

Se existir, o operador p como:

r←(g p)n;a;i;k
   a←⌽,nr←⍬⋄i0k←⍴a⋄→C
A: B×⍳r≡⍬⋄rg¨r
B: rr,⊂ia
C: A×⍳ki+←1
   r←⌽r

O operador p acima seria tal que se g for uma função de 1 argumento (monádico?), Deve ser:

"g f a a a a" is "a ga gga ggga"

a solução seria pheraps 15 caracteres

  g←{⊃+/⌽∘⍉ p 4⍴⊂⍵}
  a2 21 3 2 4
  g a
10 10 
10 10 
  g 1
4

Mas poderia ser melhor um operador "composto em tempo" d tal que "3 df w" seja f (f (f (w))).

Agora eu escrevi algo, mas é muito frágil sem a necessidade de verificação de tipo.

Mas eu gosto mais do operador q que repete a composição de f com o argumento m (não está completo porque os casos de erro dos tipos não estão escritos)

r←(n q f)m;i;k;l
   r←⍬⋄k←⍴,n⋄→A×⍳k1i0⋄→D
C: rr,⊂(in)q f m
D: C×⍳ki+←1
   0
A: lnrm⋄→0×⍳n0
B: l-←1rf r⋄→B×⍳l1

a solução seria 17 caracteres, mas eu prefiro

  g←{⊃+/(0..3)q(⌽⍉)⍵}
  fmt g a
2─────┐
2 10 10
 10 10
└~─────┘
  fmt g 1
4
~

270 poderia ser justo ⍉⌽e a coisa toda é adequada para um trem
ngn

Se existir um f tal que gfwwww é w gw GGW gggw a resposta seria + / ⌽⍉f 4 / rho w
RosLuP

Você quer dizer +/⌽∘⍉f 4⍴⊂⍵? Para obter quatro cópias , primeiro você deve anexá-lo . Ter ⌽⍉como um operando para f, você deve compor-lo em uma única função como esta: ⌽∘⍉. O misterioso fpode ser varrido (barra invertida), mas há outro detalhe a ser resolvido - ⌽∘⍉receberá um argumento à esquerda, portanto devemos ignorá-lo: +/{⌽⍉⍵}\4⍴⊂⍵ou +/⊢∘⌽∘⍉\4⍴⊂⍵.
NGN

No meu primeiro comentário que eu estava sugerindo este trem: ⊢ + ⌽∘⍉ + ⌽∘⊖ + ⍉∘⌽. Isso pode levar a soluções ainda mais curtas se você reorganizar os rabiscos de maneira inteligente e fazer bom uso dos trens.
NGN

@ngn mesmo um simples {⍵ + ⍺} \ 1 2 3 4 retorna um erro de domínio
RosLuP

2

K4 / K (oK) , 23 8 bytes

Solução:

+/(|+:)\

Experimente online!

Exemplo:

+/(|+:)\5 5#14 2 5 10 2 18 9 12 1 9 3 1 5 11 14 13 20 7 19 12 2 1 9 5 6
24 29 31 41 24
41 49 31 49 29
31 31 20 31 31
29 49 31 49 41
24 41 31 29 24

Explicação:

Agradecemos a ngn pela técnica de transformação simplificada.

+/(|+:)\ / the solution
       \ / converge
  (   )  / function to converge
    +:   / flip
   |     / reverse
+/       / sum over the result

Extra:

Em Q isso pode ser escrito como

sum (reverse flip @) scan


Eu sabia que havia uma maneira melhor de aplicar as transformações!
Streetster

+ / (| + :) \ tio.run/##y9bNz/7/X1tfo0bbSjPGWMFY2UjBVMFCwVjB0AhImQGhocH//wA infelizmente é a mesma contagem ... Gah não consegue descobrir a marcação no celular.
Streetster

Parece que a marcação nos comentários tem um bug, não apenas no celular - barra invertida antes que a cotação traseira estrague tudo. Eu o evitei inserindo um espaço.
NGN

2

Ruby , 74 72 66 bytes

->a{r=0...a.size;r.map{|i|r.map{|j|(0..3).sum{i,j=j,~i;a[i][j]}}}}

Experimente online!

Isso funciona elemento a elemento, localizando matematicamente os elementos associados, em vez de girar a matriz. A parte principal éi,j=j,~i , que gira (i, j) no sentido horário 90 graus.

-2 bytes graças ao Sr. Xcoder

-6 bytes por causa de sum



1

Ruby 89 79 bytes

-10 bytes graças ao Unihedron

->m{n=m;3.times{n=n.zip(m=m.transpose.reverse).map{|i,j|i.zip(j).map &:sum}};n}

Experimente online!


1
Tenho certeza que você pode substituir .map &:duppor *1para cortar muitos caracteres. array*lengthcria uma nova matriz e é uma maneira útil de clonar superficialmente.
Unihedron

Na verdade, n=*mé ainda mais curto.
Unihedron

@Unihedron esse é o problema, eu preciso clone profundo
asone Tuhid

Parece-me que isso não afeta a saída; Eu brincava com ele em seu link "experimentá-lo on-line" e a saída parece permanecer correta com que a mudança
Unihedron

Você está certo, na verdade você nem precisa de um clone superficial, transposecuida disso #
Asone Tuhid



1

Casca , 9 bytes

F‡+↑4¡(↔T

Experimente online!

Explicação

F‡+↑4¡(↔T)  -- implicit input M, for example: [[1,0,1],[2,3,4],[0,0,2]]
     ¡(  )  -- repeat infinitely times starting with M  
        T   -- | transpose: [[1,2,0],[0,3,0],[1,4,2]]
       ↔    -- | reverse: [[1,4,2],[0,3,0],[1,2,0]]
            -- : [[[1,0,1],[2,3,4],[0,0,2]],[[1,4,2],[0,3,0],[1,2,0]],[[2,0,0],[4,3,2],[1,0,1]],[[0,2,1],[0,3,0],[2,4,1]],[[1,0,1],[2,3,4],[0,0,2]],…
   ↑4       -- take 4: [[[1,0,1],[2,3,4],[0,0,2]],[[1,4,2],[0,3,0],[1,2,0]],[[2,0,0],[4,3,2],[1,0,1]],[[0,2,1],[0,3,0],[2,4,1]]]
F           -- fold (reduce) the elements (example with [[1,0,1],[2,3,4],[0,0,2]] [[1,4,2],[0,3,0],[1,2,0]])
 ‡+         -- | deep-zip addition (elementwise addition): [[2,4,3],[2,6,4],[1,2,2]]
            -- : [[4,6,4],[6,12,6],[4,6,4]]

1

tinylisp , 132 bytes

Vamos dar transposeuma volta na função de biblioteca recentemente adicionada !

(load library
(d T transpose
(d R(q((m #)(i #(c m(R(reverse(T m))(dec #)))(
(q((m)(foldl(q(p(map(q((r)(map sum(T r))))(T p))))(R m 4

A última linha é uma função lambda sem nome que executa a soma da rotação. Para realmente usá-lo, você precisará usá d-lo para vinculá-lo a um nome. Experimente online!

Ungolfed, com comentários

(load library) (comment Get functions from the standard library)

(comment Rotating a matrix by 90 degrees is just transpose + reverse)
(def rotate
 (lambda (matrix)
  (reverse (transpose matrix))))

(comment This function recursively generates a list of (count) successive rotations
          of (matrix))
(def rotations
 (lambda (matrix count)
  (if count
   (cons matrix
    (rotations (rotate matrix) (dec count)))
   nil)))

(comment To add two matrices, we zip them together and add the pairs of rows)
(def matrix-add
 (lambda two-matrices
  (map row-sum (transpose two-matrices))))

(comment To add two rows of a matrix, we zip them together and add the pairs of numbers)
(def row-sum
 (lambda (two-rows)
  (map sum (transpose two-rows))))

(comment Our final function: generate a list containing four rotations of the argument
          and fold them using matrix-add)
(def rotated-sum
 (lambda (matrix)
  (foldl matrix-add (rotations matrix 4))))

1

Anexo , 20 bytes

Sum@MatrixRotate&0:3

Experimente online!

Explicação

Sum@MatrixRotate&0:3

MatrixRotate&0:3expande-se para, com entrada x, MatrixRotate[x, 0:3]que, por sua vez, para exapnds [MatrixRotate[x, 0], MatrixRotate[x, 1], MatrixRotate[x, 2], MatrixRotate[x, 3]]. Ou seja, vetoriza sobre o RHS. Em seguida, Sumassume a soma de todas essas matrizes em um nível. Isso fornece o resultado desejado.


1

Java 8, 135 133 bytes

a->{int l=a.length,r[][]=new int[l][l],i=0,j;for(;i<l;i++)for(j=0;j<l;)r[i][j]=a[i][j]+a[j][l+~i]+a[l+~i][l-++j]+a[l-j][i];return r;}

-2 bytes graças a @ceilingcat .

Explicação:

Experimente online.

a->{                        // Method with integer-matrix as both parameter and return-type
  int l=a.length,           //  Dimensions of the input-matrix
      r[][]=new int[l][l],  //  Result-matrix of same size
      i=0,j;                //  Index-integers
  for(;i<l;i++)             //  Loop over the rows
    for(j=0;j<l;)           //   Loop over the columns
      r[i][j]=              //    Set the cell of the result-matrix to:
              a[i][j]+a[j][l+~i]+a[l+~i][l-++j]+a[l-j][i];
                            //     The four linked cells of the input-matrix
  return r;}                //  Return the result-matrix
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.