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!

Stewie Griffin
fonte

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.

Mr. Xcoder
fonte
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.

Luis Mendo
fonte
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.

Furioso
fonte
5

Wolfram Language (Mathematica) , 28 bytes

Sum[a=Reverse@a,{a=#;4}]&

é \[Transpose].

Experimente online!

alefalpha
fonte
Ótima solução. Eu tentei ReplacePart[#,{a_,b_}:>Tr@Extract[#,{{a,b},{b,-a},{-a,-b},{-b,a}}]]&e tambémPlus@@NestList[Reverse@#&,#,3]&
Kelly Lowder
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.

Lyndon White
fonte
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
LukeS
fonte
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
Suever
fonte
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)
Stewie Griffin
fonte
3

J , 16 15 bytes

[:+/|.@|:^:(<4)

Experimente online!

FrownyFrog
fonte
1
Este é um desafio perfeito para ^:. Solução inteligente!
cole
Essa é uma solução elegante!
Galen Ivanov
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)
Luis Mendo
fonte
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!

Florian
fonte
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)
Neil
fonte
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.
Mr. Xcoder
fonte
2

Python 2 , 76 bytes

f=lambda x,k=-2:k*x or[map(sum,zip(*r))for r in zip(x,f(zip(*x)[::-1],k+1))]

Experimente online!

Dennis
fonte
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
~
RosLuP
fonte
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
rua
fonte
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

MegaTom
fonte
1

Python 3 , 105 102 bytes

3 bytes graças ao Sr. Xcoder.

def f(a):l=len(a)-1;r=range(l+1);return[[a[i][j]+a[l-j][i]+a[l-i][l-j]+a[j][l-i]for j in r]for i in r]

Experimente online!

Freira Furada
fonte
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!

Asone Tuhid
fonte
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]]
ბიმო
fonte
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))))
DLosc
fonte
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.

Conor O'Brien
fonte
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
Kevin Cruijssen
fonte