Podsumowanie rotacji

26

Weź wejściową macierz kwadratową zawierającą dodatnie liczby całkowite i oblicz „obróconą sumę” macierzy.

Obrócona suma:

Weź sumę oryginalnej matrycy i tej samej matrycy obróconej o 90, 180 i 270 stopni.

Załóżmy, że macierz jest:

 2    5    8
 3   12    8
 6    6   10

wówczas obrócona suma będzie wynosić:

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

Przypadki testowe:

Wejście i wyjście oddzielone myślnikami, różne przypadki testowe oddzielone znakiem nowej linii. Przypadki testowe w wygodniejszych formatach można znaleźć tutaj .

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

Najkrótszy kod w bajtach w każdym języku wygrywa. Zachęcamy do wyjaśnień!

Stewie Griffin
źródło

Odpowiedzi:

9

Python 2 , 78 bajtów

Dzięki Dennisowi za grę w golfa o dwa bajty od mojego poprzedniego rekurencyjnego podejścia.

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

Wypróbuj online! lub Zobacz zestaw testowy.


Python 2 , 80 81 83 85 bajtów (nierekurencyjne)

Pobiera dane wejściowe jako listę singletonów .

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

Wypróbuj online!

Funkcjonalność kodu

Ponieważ jest to dość długa analiza całego, sprawdźmy to kawałek po kawałku:

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.

A dla drugiego programu:

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: Wygeneruj listę potrzebnych macierzy, obracając dane wejściowe 3 razy o 90 stopni i zbierając wyniki. Następnie uzyskaj sumy kolumn każdej macierzy w transpozycji wyniku.

Pan Xcoder
źródło
f=lambda*l:l[3:]and[map(sum,zip(*d))for d in zip(*l)]or f(zip(*l[0][::-1]),*l)zapisuje dwa bajty z „normalnym” wejściem. Wypróbuj online!
Dennis
@Dennis Dziękujemy! Z lambda*ljakiegoś powodu myślałem, że nie jest możliwe w Pythonie 2.
Pan Xcoder,
Nie można tego zrobić x,*y=1,2,3w Python 2.7 ani [*x]w Python 3.4, ale wyrażenia oznaczone gwiazdką mogą być użyte jako argumenty funkcji nawet w Python 1.6. Wypróbuj online!
Dennis
8

Oktawa , 29 bajtów

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

Wypróbuj online!

Wyjaśnienie

Dodaje to macierz wejściową z obróconą o 90 stopni wersją samego siebie. Wynik jest następnie dodawany z obróconą o 180 stopni wersją samego siebie.

Luis Mendo
źródło
5

Czysty , 110 bajtów

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

Wypróbuj online!

Z matematyki:

  • X = transpose(reverse M): Obrót o 90 stopni
  • Y = reverse(map reverse M): Obrót o 180 stopni
  • Z = reverse(transpose M): Obrót o 270 stopni

Ten zamki operatora dodawania nad Mi X, jak Yi Z, po czym na podstawie wyników.

Obrzydliwe
źródło
5

Wolfram Language (Mathematica) , 28 bajtów

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

jest \[Transpose].

Wypróbuj online!

alephalpha
źródło
Niezłe rozwiązanie. Próbowałem ReplacePart[#,{a_,b_}:>Tr@Extract[#,{{a,b},{b,-a},{-a,-b},{-b,a}}]]&takżePlus@@NestList[Reverse@#&,#,3]&
Kelly Lowder,
5

Julia 0.6 , 29 bajtów

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

Wypróbuj online!

Nie mogłem zejść poniżej rozwiązania LukeSa

Ale próbując wymyśliłem to, co moim zdaniem jest trochę urocze.

Najpierw redefiniujemy mnożenie jako operację obracania, w której po raz pierwszy jest liczba obrotów. Skoro Julia mnoży się przez zestawienie, to: 1xstaje się rotr90(x,1)i 3xstaje się rotr90(x,3)itp.

Następnie wypisujemy sumę.

Lyndon White
źródło
5

Julia 0.6 , 28 24 bajtów

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

Wypróbuj 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
Łukasza
źródło
1
Warto być może zauważyć, że wykonanie [1]przykładu powinno ~reshape([1], (1,1))wystarczyć, ponieważ tak właśnie deklaruje się macierz 1x1 w Julii 0.6.
Lyndon White
4

MATL , 9 bajtów

i3:"G@X!+

Wypróbuj w MATL Online

Wyjaśnienie

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
źródło
4

Oktawa , 33 bajty

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

Wypróbuj online!

Wyjaśnienie:

(r=@rot90)w sposób liniowy tworząc uchwyt funkcyjny rsłużący do obracania matrycy o 90 stopni. Jeśli drugi argument kdaje się rwówczas obracać MATRIX k*90stopni. Odpowiada to pseudo kodowi:

a + rot90(a) + rot180(a) + rot270(a)
Stewie Griffin
źródło
3

J , 16 15 bajtów

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

Wypróbuj online!

FrownyFrog
źródło
1
To idealne wyzwanie dla ^:. Sprytne rozwiązanie!
cole
To eleganckie rozwiązanie!
Galen Iwanow
3

MATL , 7 bajtów

,t@QX!+

Wypróbuj w MATL Online!

Wyjaśnienie

Port mojej odpowiedzi 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
źródło
3

R , 69 64 bajtów

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

Wypróbuj online!


Próba numer trzy w codegolf. Od 69 do 64 bajtów dzięki Giuseppe!

Florian
źródło
Przejście ado argumentu funkcji pozwoli zaoszczędzić bajty, umożliwiając pozbycie się {}całego ciała funkcji. Ponadto przeniesienie podejścia Octave Luisa Mendo może zaoszczędzić trochę bajtów? Wreszcie, nie jestem w 100% pewien, ale jest to t(apply(x,2,rev))równoważne z apply(x,1,rev)?
Giuseppe
Dzięki, mogłem poprawić dzięki końcówce 1 i 3. Nie udało się oszczędność bajtów dodając argument n, aby a()powtórzyć operację chociaż.
Florian
1
Miałem na myśli coś takiego
Giuseppe
2

JavaScript (ES6), 77 bajtów

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
źródło
2

Galaretka , 7 bajtów

ṚZ$3СS

Wypróbuj online!

Zaoszczędzono 1 bajt dzięki Erikowi Outgolfer (również dzięki sugestii naprawy błędu).

W jaki sposób?

СZ 3СS || || Pełny program (monadyczny).

   3С || Zrób to 3 razy i zbierz wyniki na liście
  $ || -> Zastosuj dwa ostatnie łącza jako monadę
Ṛ || –––> Rewers,
 Z || –––> Transpozycja.
      S || Podsumowanie.
Pan Xcoder
źródło
2

Python 2 , 76 bajtów

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

Wypróbuj online!

Dennis
źródło
2

APL (Dyalog Classic) , 17 bajtów

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

Wypróbuj online!

APL NARS 34 bajtów 21 17 znaków

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

-2 znaki dzięki ngn

-2 znaki, ponieważ operator złożony ∘ wydaje się mieć pierwszeństwo na +

wydaje się, że rota obróć o od 90 °, ⌽⊖a obróć od 180 °, ⌽⍉⌽⊖a obróć od 270 ° jak ⍉⌽

Jeśli istnieje operator p jako:

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

Operator p powyżej byłby taki, że jeśli g jest funkcją 1-argumentową (monadyczną?), Powinno być:

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

rozwiązaniem byłyby pherapy 15 znaków

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

Ale może być lepszy jeden operator „skomponowany n czas” d taki, że „3 df w” to f (f (f (w))).

Teraz coś napisałem, ale jest to zbyt kruche bez konieczności sprawdzania typu.

Ale bardziej podoba mi się operator q, który powtarza komponowanie fz argumentem m (nie jest kompletny, ponieważ przypadki błędów typów nie są zapisywane)

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

rozwiązaniem byłoby 17 znaków, ale wolę to

  g←{⊃+/(0..3)q(⌽⍉)⍵}
  fmt g a
2─────┐
2 10 10
 10 10
└~─────┘
  fmt g 1
4
~
RosLuP
źródło
270 może być sprawiedliwe ⍉⌽i całość nadaje się do pociągu
ngn
Jeśli istnieje jeden taki, że gfwwww jest w gw ggw gggw, odpowiedzią byłoby + / ⌽⍉f 4 / rho w
RosLuP
Masz na myśli +/⌽∘⍉f 4⍴⊂⍵? Aby otrzymać cztery kopie , najpierw należy dołączyć . Aby mieć ⌽⍉jako argument do fnależy komponować je w jednej funkcji takich jak to: ⌽∘⍉. Tajemnicze fmoże być skanowanie (ukośnik odwrotny), ale należy zająć się jeszcze jednym szczegółem - ⌽∘⍉otrzymamy lewy argument, więc musimy go zignorować: +/{⌽⍉⍵}\4⍴⊂⍵lub +/⊢∘⌽∘⍉\4⍴⊂⍵.
ngn
W moim pierwszym komentarzu ja sugerowałem tego pociągu: ⊢ + ⌽∘⍉ + ⌽∘⊖ + ⍉∘⌽. Może to prowadzić do jeszcze krótszych rozwiązań, jeśli sprytnie przestawisz squiggles i dobrze wykorzystasz pociągi.
ngn
@ngn nawet prosty {⍵ + ⍺} \ 1 2 3 4 błąd domeny zwrotnej
RosLuP
2

K4 / K (oK) , 23 8 bajtów

Rozwiązanie:

+/(|+:)\

Wypróbuj online!

Przykład:

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

Wyjaśnienie:

Dzięki ngn za uproszczoną technikę transformacji.

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

Dodatkowy:

W Q można to zapisać jako

sum (reverse flip @) scan
streetster
źródło
I wiedział, nie było lepszego sposobu, aby zastosować transformacje!
streetster
+ / (| + :) \ tio.run/##y9bNz/7/X1tfo0bbSjPGWMFY2UjBVMFCwVjB0AhImQGhocH//wA jest niestety taką samą liczbą ... Gah nie może ustalić znaczników na urządzeniach mobilnych.
streetster
Wygląda na to, że znaczniki w komentarzach zawierają błąd, nie tylko na urządzeniach mobilnych - odwrotny ukośnik, zanim cofnięcie cudzysłowu coś popsunie. Uniknąłem tego, wstawiając spację.
ngn
2

Rubinowy , 74 72 66 bajtów

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

Wypróbuj online!

Działa to na zasadzie element po elemencie, znajdując powiązane elementy matematycznie, zamiast obracać tablicę. Kluczową częścią jest i,j=j,~i, która obraca się (i, j) zgodnie z ruchem wskazówek zegara o 90 stopni.

-2 bajty dzięki Mr. Xcoder

-6 bajtów z powodu sum

MegaTom
źródło
1

Python 3 , 105 102 bajtów

3 bajty dzięki Mr. 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]

Wypróbuj online!

Leaky Nun
źródło
1

Ruby 89 79 bajtów

-10 bajtów dzięki Unihedron

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

Wypróbuj online!

Asone Tuhid
źródło
1
Jestem całkiem pewien, że można zastąpić .map &:dupz *1odciąć dużo znaków. array*lengthtworzy nową tablicę i jest przydatnym sposobem na płytki klon.
Unihedron
W rzeczywistości n=*mjest jeszcze krótszy.
Unihedron
@ Jednorożec, to jest problem, muszę głęboko sklonować
Asone Tuhid
Wydaje mi się, że nie wpływa to na wynik; Zrobiłem to z linkiem „spróbuj online”, a wynik wydaje się być poprawny z tą zmianą
Unihedron
Masz rację, właściwie nie potrzebujesz nawet płytkiego klonu, transposezajmuje się tym
Asone Tuhid
1

Łuska , 9 bajtów

F‡+↑4¡(↔T

Wypróbuj online!

Wyjaśnienie

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]]
ბიმო
źródło
1

tinylisp , 132 bajty

Przyjrzyjmy się ostatnio dodanej funkcji biblioteki transpose!

(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

Ostatni wiersz to nienazwana funkcja lambda, która wykonuje sumowanie rotacji. Aby go faktycznie użyć, powinieneś użyć, daby powiązać go z nazwą. Wypróbuj online!

Bez golfa, z komentarzami

(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
źródło
1

Attache , 20 bajtów

Sum@MatrixRotate&0:3

Wypróbuj online!

Wyjaśnienie

Sum@MatrixRotate&0:3

MatrixRotate&0:3rozszerza się z wejścia x, MatrixRotate[x, 0:3], co z kolei exapnds do [MatrixRotate[x, 0], MatrixRotate[x, 1], MatrixRotate[x, 2], MatrixRotate[x, 3]]. Innymi słowy, wektoryzuje on RHS. Następnie Sumbierze sumę wszystkich tych macierzy o jeden poziom. Daje to pożądany rezultat.

Conor O'Brien
źródło
1

Java 8, 135 133 bajtów

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 bajty dzięki @ceilingcat .

Wyjaśnienie:

Wypróbuj 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
źródło