¡Dobla una matriz!

13

Dada una matriz, sume sus valores arriba / abajo o izquierda / derecha para formar una X, dóblela hacia arriba y devuelva la lista. Describo el algoritmo aquí:

Algoritmo

Su entrada será una matriz cuadrada de enteros de tamaño impar dentro de la capacidad numérica razonable de su idioma.

Tomemos la siguiente matriz como ejemplo:

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

Primero, agregue cada número al número más cercano que esté en la diagonal principal o antidiagonal. Es decir, divida la matriz en cuatro secciones a lo largo de la diagonal principal y antidiagonal, y luego sume todos los números en cada sección hacia el centro, así:

1   2   3   2   1
    ↓   ↓   ↓    
0 → 3   2   3 ← 0
        ↓        
4 → 2 → 5 ← 6 ← 3
        ↑        
7 → 4   7   9 ← 4
    ↑   ↑   ↑    
0   6   7   2   5

Este paso da el siguiente resultado:

1        1
  5    5
    39
  17  15
0        5

Luego, lo doblamos al aplanar la X y entrelazar los elementos con la parte superior izquierda primero y la inferior izquierda última. Esto da el siguiente resultado:

1, 0, 5, 17, 39, 5, 15, 1, 5

Puedes imaginar esto como estirar la diagonal principal y rotarla en sentido antihorario.

Este es el resultado final.

Desafío

Implementa este algoritmo. Se aplican lagunas estándar. Todos los formatos razonables de E / S son aceptables.

Casos de prueba

Input
Output

1 2 3 2 1
0 3 2 3 0
4 2 5 6 3
7 4 7 9 4
0 6 7 2 5

1, 0, 5, 17, 39, 5, 15, 1, 5

1 2 3 4 5
5 4 3 2 1
1 3 5 7 9
0 9 8 7 6
6 7 8 9 0

1, 6, 11, 16, 47, 7, 22, 5, 0

1 3 7 4 8 5 3
8 4 7 5 3 8 0
0 6 3 6 9 8 4
2 6 5 8 7 4 2
0 6 4 3 2 7 5
0 6 7 8 5 7 4
8 5 3 2 6 7 9

1, 8, 15, 11, 23, 20, 62, 32, 25, 13, 18, 3, 9
Hiperneutrino
fuente
¿Se puede agregar un caso de prueba de matriz "no 5 × 5"?
totalmente humano
1
@icrieverytim aquí tienes
HyperNeutrino

Respuestas:

7

JavaScript, 113 bytes

s=>(l=s.length-1,a=[],s.map((v,y)=>v.map((n,x)=>a[q=2*[x,y,l-y].sort((u,v)=>u-v)[1]+(y>l/2),q-=q>l]=~~a[q]+n)),a)

tsh
fuente
Umm .. por qué ~~? Se neutralizan entre sí, por lo que no hay necesidad de ellos.
Kevin Cruijssen
2
@KevinCruijssen ~~undefined==0, así que esto es más golfista que (a[q]||0).
Neil
@Neil Ah, no había pensado en eso undefined. Cuando copié el caso de prueba utilizado por tsh , noté que funcionaba sin el ~~. Y como ~~xes similar-(-x) neutralizarse entre sí, pensé que de alguna manera fue puesto allí por accidente. Gracias por la corrección.
Kevin Cruijssen
5

Jalea , 25 23 21 bytes

AṂ×ṠṚ
LHŒRṗ2Ç€ḅLĠịFS€

Pruébalo en línea!

Versión alternativa, 19 bytes.

AṂ×ṠṚ
LHŒRṗ2Ç€ĠịFS€

Esto no solía funcionar porque se Ġcomportó incorrectamente para matrices anidadas. La única diferencia es que los pares [q, p] mencionados en Cómo funciona se ordenan lexicográficamente en lugar de asignarlos a p + nq antes de ordenarlos.

Pruébalo en línea!

Antecedentes

Comenzamos reemplazando sus elementos con coordenadas, aumentando hacia la izquierda y hacia abajo y colocando (0, 0) en el centro de la matriz.

Para una matriz M de 7x7 , obtenemos las siguientes coordenadas.

(-3,-3) (-3,-2) (-3,-1) (-3, 0) (-3, 1) (-3, 2) (-3, 3)
(-2,-3) (-2,-2) (-2,-1) (-2, 0) (-2, 1) (-2, 2) (-2, 3)
(-1,-3) (-1,-2) (-1,-1) (-1, 0) (-1, 1) (-1, 2) (-1, 3)
( 0,-3) ( 0,-2) ( 0,-1) ( 0, 0) ( 0, 1) ( 0, 2) ( 0, 3)
( 1,-3) ( 1,-2) ( 1,-1) ( 1, 0) ( 1, 1) ( 1, 2) ( 1, 3)
( 2,-3) ( 2,-2) ( 2,-1) ( 2, 0) ( 2, 1) ( 2, 2) ( 2, 3)
( 3,-3) ( 3,-2) ( 3,-1) ( 3, 0) ( 3, 1) ( 3, 2) ( 3, 3)

Ahora calculamos el valor absoluto mínimo de cada par de coordenadas y multiplicamos los signos de ambas coordenadas por él, asignando (i, j) a (signo (i) m, signo (j) m) , donde m = min (| i | , | j |) .

(-3,-3) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-3, 3)
(-2,-2) (-2,-2) (-1,-1) ( 0, 0) (-1, 1) (-2, 2) (-2, 2)
(-1,-1) (-1,-1) (-1,-1) ( 0, 0) (-1, 1) (-1, 1) (-1, 1)
( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0) ( 0, 0)
( 1,-1) ( 1,-1) ( 1,-1) ( 0, 0) ( 1, 1) ( 1, 1) ( 1, 1)
( 2,-2) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 2, 2)
( 3,-3) ( 2,-2) ( 1,-1) ( 0, 0) ( 1, 1) ( 2, 2) ( 3, 3)

Los elementos de la matriz que corresponden al mismo par deben sumarse. Para determinar el orden de las sumas, asignamos cada par (p, q) a p + nq , donde n es el número de filas / columnas de M .

-24 -16  -8   0   6  12  18
-16 -16  -8   0   6  12  12
 -8  -8  -8   0   6   6   6
  0   0   0   0   0   0   0
 -6  -6  -6   0   8   8   8
-12 -12  -6   0   8  16  16
-18 -12  -6   0   8  16  24

El orden de las sumas corresponde al orden de los enteros que corresponden a sus sumandos.

Cómo funciona

LHŒRṗ2Ç€ḅLĠịFS€  Main link. Argument: M (matrix)

L                Compute n, the length (number of rows) of M.
 H               Halve it.
  ŒR             Symmetric range; map t to [-int(t), ..., 0, int(t)].
    ṗ2           Compute the second Cartesian power, yielding all pairs [i, j]
                 with -t ≤ i, j ≤ t.
      ǀ         Map the helper link over the resulting array of pairs.
         L       Yield n.
        ḅ        Unbase; map each pair [q, p] to (p + nq).
          Ġ      Group the indices of the resulting array of n² integers by their
                 corresponding values, ordering the groups by the values.
            F    Flatten M.
           ị     Index into the serialized matrix.
             S€  Compute the sum of each group.


AṂ×ṠṚ            Helper link. Argument: [i, j] (index pair)

A                Absolute value; yield [|i|, |j|].
 Ṃ               Minimum; yield m := min(|i|, |j|).
   Ṡ             Sign; yield [sign(i), sign(j)].
  ×              Multiply; yield [p, q] := [sign(i)m, sign(j)m].
    Ṛ            Reverse; yield [q, p].
Dennis
fuente
55
esto es brillante.
Uriel
5

Python, 159158 bytes

def f(m):l=len(m)-1;r=range(1,l);return m[0][::l]+f([[sum(m[x][1%y*y:(y>l-2)-~y])+m[0][y]*(x<2)+m[l][y]*(x>l-2)for y in r]for x in r])+m[l][::l]if l else m[0]

Pruébalo en línea!

KSab
fuente
1
y+1+(y>l-2)puede ser (y>l-2)-~y.
Jonathan Frech
2

APL (Dyalog) , 60 bytes *

En colaboración con mi colega Marshall .

Prefijo anónimo lambda. Toma la matriz como argumento y devuelve el vector. Asume ⎕IO ( I ndex O rigin) a ser cero, que es predeterminado en muchos sistemas.

{(,⍉{+/,(s×-×⍺)↓⍵×i∊¨⍨s←⌊⊃r÷2}⌺r⊢⍵)/⍨,(⊢∨⌽)=/¨i←⍳r←⍴⍵}

Pruébalo en línea!

{... } lambda anónimo; es el argumento correcto (como la letra más a la derecha del alfabeto griego):

⍴⍵ forma del argumento (lista de dos elementos idénticos)

r← almacenar como r(como en r ho)

 todos los of nices de una matriz de ese tamaño, es decir (0 0), (0 1)...

i← almacenar en i(como en i ota)

=/¨ Booleano donde las coordenadas son iguales (es decir, la diagonal)

(... ) aplique esta función de prefijo tácito anónimo:

   invertir el argumento

  ⊢∨ O que con el argumento no modificado

, ravel (enderezar en una lista simple)

 Ahora tenemos una máscara booleana para las diagonales.

(... )/⍨ use eso para filtrar lo siguiente:

  ⊢⍵ ceder (para separarse de r) el argumento

  {}⌺r Llame al siguiente infijo anónimo lambda en cada elemento, con el rvecindario (rellenado con ceros según sea necesario) como argumento correcto ( ), y una lista de dos elementos de filas, columnas rellenadas con números (negativo para abajo / derecha, cero para ninguno) como argumento izquierdo ( ):

   r÷2 dividir rcon dos

    elige el primer elemento (son idénticos)

    pisalo

   s← almacenar como s(para s hape)

   i∊⍨¨ para cada elemento de i, Boolean si ses miembro del mismo

   ⍵× multiplicar el barrio con el

   ()↓ Suelte el siguiente número de filas y columnas (negativo para abajo / derecha):

    ×⍺ signo del argumento izquierdo (es decir, la dirección de los rellenos)

    - negar

     multiplicar scon eso

   , ravel (enderezar en la lista)

   +/ suma (más reducción)

Ahora tenemos una matriz completa de sumas, pero necesitamos filtrar todos los valores leídos en columnas.

   transponer

  , ravel (enderezar en una lista simple)


* Contando como ⎕U233A . Pruébalo en línea!

Adán
fuente