Somme de rotation

26

Prenez une matrice carrée contenant des entiers positifs en entrée et calculez la «somme pivotée» de la matrice.

Somme tournée:

Prenez la somme de la matrice d'origine et la même matrice tournée de 90, 180 et 270 degrés.

Supposons que la matrice soit:

 2    5    8
 3   12    8
 6    6   10

alors la somme pivotée sera:

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

Cas de test:

Entrée et sortie séparées par des tirets, différents cas de test séparés par une nouvelle ligne. Des cas de test dans des formats plus pratiques peuvent être trouvés ici .

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

Le code le plus court en octets dans chaque langue gagne. Les explications sont fortement encouragées!

Stewie Griffin
la source

Réponses:

9

Python 2 , 78 octets

Merci à Dennis d' avoir joué deux octets sur ma précédente approche récursive.

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

Essayez-le en ligne! ou Voir une suite de tests.


Python 2 , 80 81 83 85 octets (non récursif)

Prend l'entrée en tant que liste singleton .

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

Essayez-le en ligne!

Fonctionnalité de code

Comme c'est assez long pour l'analyser dans son ensemble, examinons-le morceau par morceau:

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.

Et pour le deuxième programme:

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: générer la liste des matrices nécessaires en faisant tourner l'entrée 3 fois de 90 degrés et en collectant les résultats. Ensuite, récupérez les sommes des colonnes de chaque matrice dans la transposition du résultat.

M. Xcoder
la source
f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)enregistre deux octets avec une entrée "normale". Essayez-le en ligne!
Dennis
@Dennis Merci! Je pensais que ce lambda*ln'était pas possible dans Python 2 pour une raison quelconque.
M. Xcoder
Vous ne pouvez pas le faire x,*y=1,2,3en Python 2.7 ou [*x]en Python 3.4, mais les expressions étoilées peuvent être utilisées pour les arguments de fonction même en Python 1.6. Essayez-le en ligne!
Dennis
8

Octave , 29 octets

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

Essayez-le en ligne!

Explication

Cela ajoute la matrice d'entrée avec une version pivotée de 90 degrés d'elle-même. Le résultat est ensuite ajouté avec une version pivotée à 180 degrés de lui-même.

Luis Mendo
la source
5

Propre , 110 octets

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

Essayez-le en ligne!

Des matricies:

  • X = transpose(reverse M): Rotation à 90 degrés
  • Y = reverse(map reverse M): Rotation à 180 degrés
  • Z = reverse(transpose M): Rotation à 270 degrés

Cela zippe l'opérateur d'addition sur Met X, ainsi que Yet Z, puis sur les résultats.

Οurous
la source
5

Julia 0,6 , 29 octets

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

Essayez-le en ligne!

Je ne pouvais pas descendre en dessous de la solution de LukeS

Mais en essayant, j'ai trouvé cela, qui je pense est plutôt mignon.

D'abord, nous redéfinissons la multiplication comme étant l'opération de rotation, où il y a la première fois le nombre de rotations. Donc depuis julia multipes par juxtaposition alors: 1xdevient rotr90(x,1)et 3xdevient rotr90(x,3)etc.

Ensuite, nous écrivons la somme.

Lyndon White
la source
5

Julia 0,6 , 28 24 octets

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

Essayez-le en ligne!

~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
la source
1
Il vaut peut-être la peine de noter que faire l' [1]exemple devrait faire ~reshape([1], (1,1))parce que c'est ainsi qu'une matrice 1x1 est déclarée en julia 0.6.
Lyndon White
4

MATL , 9 octets

i3:"G@X!+

Essayez-le sur MATL Online

Explication

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
la source
4

Octave , 33 octets

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

Essayez-le en ligne!

Explication:

(r=@rot90)d'une manière en ligne de créer une poignée de fonction rutilisée pour faire pivoter la matrice de 90 degrés. Si un deuxième argument kest donné, ril fera pivoter les k*90degrés de la matrice . C'est donc équivalent au pseudo code:

a + rot90(a) + rot180(a) + rot270(a)
Stewie Griffin
la source
3

J , 16 15 octets

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

Essayez-le en ligne!

FrownyFrog
la source
1
C'est un défi parfait pour ^:. Solution intelligente!
cole
Voilà une solution élégante!
Galen Ivanov
3

MATL , 7 octets

,t@QX!+

Essayez-le sur MATL Online!

Explication

Port de ma réponse Octave.

,        % 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
la source
3

R , 69 64 octets

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

Essayez-le en ligne!


Tentez le numéro trois au codegolf. De 69 à 64 octets grâce à Giuseppe!

Florian
la source
Passer aà un argument de fonction économisera des octets en vous permettant de vous débarrasser du {}corps de la fonction. De plus, le portage de l'approche Octave de Luis Mendo pourrait économiser quelques octets? Enfin, je ne suis pas sûr à 100% mais t(apply(x,2,rev))équivaut à apply(x,1,rev)?
Giuseppe
Merci, j'ai pu m'améliorer avec les astuces # 1 et # 3. Je n'ai pas réussi à enregistrer des octets en ajoutant un argument nà a()pour répéter l'opération.
Florian
1
Je voulais dire quelque chose comme ça
Giuseppe
2

JavaScript (ES6), 77 octets

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
la source
2

Gelée , 7 octets

ṚZ$3СS

Essayez-le en ligne!

Enregistré 1 octet grâce à Erik l'Outgolfer (également grâce à une suggestion de correction d'un bug).

Comment?

ṚZ $ 3СS || Programme complet (monadique).

   3С || Faites cela 3 fois et collectez les résultats dans une liste
  $ || -> Appliquer les deux derniers liens en monade
Ṛ || –––> Marche arrière,
 Z || –––> Transposer.
      S || Addition.
M. Xcoder
la source
2

Python 2 , 76 octets

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

Essayez-le en ligne!

Dennis
la source
2

APL (Dyalog Classic) , 17 octets

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

Essayez-le en ligne!

APL NARS 34 octets 21 17 caractères

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

-2 caractères grâce à ngn

-2 car car l'opérateur composite ∘ semble avoir la priorité sur +

il semble ⌽⍉a tourner a de 90 °, ⌽⊖a tourner a de 180 °, ⌽⍉⌽⊖a tourner a de 270 ° comme ⍉⌽

S'il existe l'opérateur p comme:

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

L'opérateur p ci-dessus serait tel que si g est une fonction à 1 argument (monadique?) Elle devrait être:

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

la solution serait phéraps 15 caractères

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

Mais pourrait être meilleur un opérateur "composé de n temps" d tel que "3 df w" soit f (f (f (w))).

Maintenant, j'ai écrit quelque chose, mais il est trop fragile sans avoir besoin de vérifier le type.

Mais j'aime plus l'opérateur q qui répète compose de f avec l'argument m (il n'est pas complet car les cas d'erreur des types ne sont pas écrits)

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

la solution serait de 17 caractères mais je la préfère

  g←{⊃+/(0..3)q(⌽⍉)⍵}
  fmt g a
2─────┐
2 10 10
 10 10
└~─────┘
  fmt g 1
4
~
RosLuP
la source
270 pourrait être juste ⍉⌽et le tout convient à un train
ngn
S'il existe un f tel que gfwwww est w gw ggw gggw la réponse serait + / ⌽⍉f 4 / rho w
RosLuP
Tu veux dire +/⌽∘⍉f 4⍴⊂⍵? Pour obtenir quatre exemplaires de , vous devez d’abord le joindre à . Avoir ⌽⍉comme un opérande f, vous devez composer en une seule fonction comme ceci: ⌽∘⍉. Le mystérieux fpourrait être scan (barre oblique inverse), mais il y a un autre détail à prendre en charge - ⌽∘⍉obtiendra un argument de gauche, nous devons donc le faire ignorer: +/{⌽⍉⍵}\4⍴⊂⍵ou +/⊢∘⌽∘⍉\4⍴⊂⍵.
ngn
Dans mon premier commentaire que je proposais ce train: ⊢ + ⌽∘⍉ + ⌽∘⊖ + ⍉∘⌽. Cela peut conduire à des solutions encore plus courtes si vous réorganisez intelligemment les gribouillis et faites bon usage des trains.
ngn
@ngn même une simple erreur de domaine {⍵ + ⍺} \ 1 2 3 4 return
RosLuP
2

K4 / K (oK) , 23 8 octets

Solution:

+/(|+:)\

Essayez-le en ligne!

Exemple:

+/(|+:)\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

Explication:

Merci à ngn pour la technique de transformation simplifiée.

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

Supplémentaire:

En Q, cela pourrait s'écrire

sum (reverse flip @) scan
streetster
la source
Je savais qu'il y avait une meilleure façon d'appliquer les transformations!
streetster
+ / (| + :) \ tio.run/##y9bNz/7/X1tfo0bbSjPGWMFY2UjBVMFCwVjB0AhImQGhocH//wA est malheureusement le même nombre ... Gah ne peut pas comprendre le balisage sur mobile.
streetster
Il semble que le balisage dans les commentaires ait un bug, non seulement sur mobile - barre oblique inverse avant que la citation inverse ne gâche les choses. Je l'ai évité en insérant un espace.
ngn
2

Rubis , 74 72 66 octets

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

Essayez-le en ligne!

Cela fonctionne élément par élément, en trouvant mathématiquement les éléments associés, au lieu de faire pivoter le tableau. La partie clé est i,j=j,~i, qui tourne (i, j) de 90 degrés dans le sens des aiguilles d'une montre.

-2 octets grâce à M. Xcoder

-6 octets en raison de sum

MegaTom
la source
1

Python 3 , 105 102 octets

3 octets grâce à M. 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]

Essayez-le en ligne!

Leaky Nun
la source
1

Ruby 89 79 octets

-10 octets grâce à Unihedron

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

Essayez-le en ligne!

Asone Tuhid
la source
1
Je suis sûr que vous pouvez remplacer .map &:duppar *1pour couper un grand nombre de caractères. array*lengthcrée un nouveau tableau et est un moyen pratique de cloner peu profond.
Unihedron
En fait, n=*mc'est encore plus court.
Unihedron
@Unihedron c'est le problème, j'ai besoin de cloner en profondeur
Asone Tuhid
Il me semble que cela n'affecte pas la sortie; Je l'ai manipulé dans votre lien "essayez-le en ligne" et la sortie semble rester correcte avec ce changement
Unihedron
Vous avez raison, en fait, vous n'avez même pas besoin d'un clone peu profond, transpose
prenez
1

Coque , 9 octets

F‡+↑4¡(↔T

Essayez-le en ligne!

Explication

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]]
ბიმო
la source
1

tinylisp , 132 octets

Prenons la fonction de bibliothèque récemment ajoutée transposepour un tour!

(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

La dernière ligne est une fonction lambda sans nom qui effectue la sommation de rotation. Pour l'utiliser réellement, vous voudrez l'utiliser dpour le lier à un nom. Essayez-le en ligne!

Non golfé, avec commentaires

(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
la source
1

Attaché , 20 octets

Sum@MatrixRotate&0:3

Essayez-le en ligne!

Explication

Sum@MatrixRotate&0:3

MatrixRotate&0:3se dilate pour, avec l' entrée x, MatrixRotate[x, 0:3]qui , à son tour , à exapnds [MatrixRotate[x, 0], MatrixRotate[x, 1], MatrixRotate[x, 2], MatrixRotate[x, 3]]. C'est-à-dire qu'il vectorise sur le RHS. Ensuite, Sumprend la somme de toutes ces matrices d'un niveau. Cela donne le résultat souhaité.

Conor O'Brien
la source
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 octets grâce à @ceilingcat .

Explication:

Essayez-le en ligne.

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
la source