Soma os deltas da minha matriz

17

fundo

Os deltas de uma matriz de números inteiros é a matriz formada pela obtenção das diferenças de elementos consecutivos. Por exemplo, [1, 2, 4, 7, 3, 9, 6]possui os seguintes deltas:[1, 2, 3, -4, 6, -3] .

Vamos agora definir os deltas de uma matriz de números inteiros como os deltas de cada linha e cada coluna que ela contém.

Como um exemplo:

Row deltas:

1 2 3 4 │ => [1, 1, 1]
4 5 6 7 │ => [1, 1, 1]
7 1 8 2 │ => [-6, 7, -6]

Column deltas (the matrix' columns have been rotated into rows for simplicity):

1 4 7 │ => [3, 3] 
2 5 1 │ => [3, -4]
3 6 8 │ => [3, 2]
4 7 2 │ => [3, -5]

O que nos fornece a seguinte lista de deltas da matriz:

[[1, 1, 1], [1, 1, 1], [-6, 7, -6], [3, 3], [3, -4], [3, 2], [3, -5]]

E como não queremos que eles sejam aninhados, achatamos essa lista:

[1, 1, 1, 1, 1, 1, -6, 7, -6, 3, 3, 3, -4, 3, 2, 3, -5]

Tarefa

Sua tarefa é somar todos os deltas de uma matriz dados como entrada. Observe que a matriz consistirá apenas de números inteiros não negativos.

Regras

  • Todas as regras padrão se aplicam.

  • Você pode assumir que a matriz contém pelo menos dois valores em cada linha e coluna; portanto, o tamanho mínimo será 2x2 .

  • Você pode pegar a matriz em qualquer formato razoável, desde que você a especifique.

  • Você não pode assumir que a matriz é quadrada.

  • Se isso puder ajudá-lo a reduzir sua contagem de bytes, opcionalmente , você poderá incluir o número de linhas e o número de colunas (olhando para você, C!).

  • Isso é código-golfe, então o código mais curto (em bytes), em cada idioma, vence!

Casos de teste

Entrada => Saída

[[1, 2], [1, 2]] => 2
[[8, 7, 1], [4, 1, 3], [5, 5, 5]] => -9
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] => 24
[[9, 9, 9, 9, 9], [9, 9, 9, 9, 9]] => 0
[[1, 3, 14], [56, 89, 20], [99, 99, 99]] => 256
[[1, 2, 3, 4], [4, 5, 6, 7], [7, 1, 8, 2]] => 9
[[13, 19, 478], [0, 12, 4], [45, 3, 6], [1, 2, 3]] => -72
Mr. Xcoder
fonte

Respostas:

12

Python 2 , 42 bytes

lambda m:sum(r[-1]-r[0]for r in m+zip(*m))

Uma função sem nome que obtém uma lista de listas me retorna o número resultante.

Experimente online!

Quão?

A soma dos deltas de uma lista é o último elemento menos o primeiro, tudo o resto é cancelado:
(r [n] -r [n-1]) + (r [n-1] -r [n-2]) + ... + (r [2] -r [1]) = r [n] -r [1]

O zip(*m)usa descompactar ( *) de mpara passar as linhas de margumentos separados para zip(intercalar) e, portanto, transpõe a matriz. No python 2, isso gera uma lista (de tuplas, mas isso é bom), para que possamos adicioná-lo (concatenar) a (with) m, percorrer todas as nossas linhas e colunas r, executar o truque acima para cada um e somar os resultados ( sum(...))

Jonathan Allan
fonte
8

R , 34 bytes

function(m)sum(diff(m),diff(t(m)))

Experimente online!

Função anônima. Originalmente, eu costumava apply(m,1,diff)obter as diferenças de linha (e 2não 1para colunas), mas olhando para a resposta de Stewie Griffin, tentei com apenas diffe funcionou.

Giuseppe
fonte
8

Oitava , 33 bytes

@(x)sum([diff(x)(:);diff(x')(:)])

Experimente online!

Explicação:

Esta é uma função anônima, tendo xcomo entrada. Ele pega a diferença entre todas as colunas e a concatena com a diferença entre as colunas da transposta de x. Em seguida, soma esse vetor ao longo da segunda dimensão.

Stewie Griffin
fonte
5

Gelatina , 5 bytes

;ZIẎS

Experimente online!

Também existem algumas versões apenas ASCII: ;ZIFS ;ZISS

Erik, o Outgolfer
fonte
5

JavaScript (ES6), 68 67 bytes

m=>m.map(r=>s+=[...l=r].pop()-r[0],s=0)|m[0].map(v=>s+=l.pop()-v)|s

Formatado e comentado

m =>                              // given a matrix m
  m.map(r =>                      // for each row r of m
    s += [...l = r].pop() - r[0], //   add to s: last value of r - first value of r
    s = 0                         //   starting with s = 0
  ) |                             //
  m[0].map(v =>                   // for each value v in the first row of m:
    s += l.pop() - v              //   add to s: last value of last row of m - v
  ) |                             //
  s                               // return s

Como o tamanho mínimo da matriz de entrada é 2x2, m.map(...)|m[0].map(...)é garantido que ele seja coagido 0. É por isso que é seguro retornar o resultado final com |s.

Casos de teste

Arnauld
fonte
5

MATL , 7 bytes

dG!dhss

Experimente online!

Explicação:

Suponha que a entrada seja

[8 7 1; 4 1 3; 5 5 5]

d        % Difference between rows of input
         % Stack:
         % [-4 -6  2; 1  4  2]
 G       % Grab the input again. Stack:
         % [-4 -6  2; 1  4  2]
         % [8 7 1; 4 1 3; 5 5 5]]
  !      % Transpose the bottom element. Stack:
         % [-4 -6  2; 1  4  2]
         % [8 4 5; 7 1 5; 1 3 5]
   d     % Difference between rows. Stack:
         % [-4 -6  2; 1  4  2]
         % [-1 -3  0; -6  2  0]
    h    % Concatenate horizontally. Stack:
         % [-4 -6  2 -1 -3  0; 1  4  2 -6  2  0]
     ss  % Sum each column, then sum all column sums. Stack:
         % -9
Stewie Griffin
fonte
4

J , 14 bytes

+/@,&({:-{.)|:

Experimente online!

Explicação

+/@,&({:-{.)|:  Input: matrix M
            |:  Transpose
     (     )    Operate on M and M'
      {:          Tail
        -         Minus
         {.       Head
   ,&           Join
+/@             Reduce by addition
milhas
fonte
3

Casca , 7 bytes

ΣṁẊ-S+T

Experimente online!

-1 graças ao Mr. Xcoder tirar meu foco longe do Se ¤e para o m(que deveria ter sido ).
-1 graças ao abuso de ZgarbS .

Explicação:

ΣṁẊ-S+T 3-function composition
    S   (x -> y -> z) (f) -> (x -> y) (g) -> x (x) (implicit): f x g x
     +    f: [x] (x) -> [x] (y) -> [x]: concatenate two lists
      T   g: [[x]] (x) -> [[x]]: transpose x
 ṁ      (x -> [y]) (f) -> [x] (x) -> [y]: map f on x and concatenate
  Ẋ       f: (x -> y -> z) (f) -> [x] (x) -> [z]: map f on splat overlapping pairs of x
   -        f: TNum (x) -> TNum (y) -> TNum: y - x
Σ       [TNum] (x) -> TNum: sum x
Erik, o Outgolfer
fonte
Sim, 8 bytes , usando .
Xcoder 10/09/19
8 bytes também, usando sua abordagem.
Mr. Xcoder
@ Mr.Xcoder wow esqueci disso
Erik o Outgolfer
3

APL, 18 15 bytes

{-+/∊2-/¨⍵(⍉⍵)}

Experimente online!

Zacharý
fonte
13 bytes -+/∘∊(2-⍨/⍉⍪⊢)
Uriel
@Uriel que funciona apenas para matrizes quadradas
NGN
3

Haskell , 60 bytes

e=[]:e
z=zipWith
f s=sum$(z(-)=<<tail)=<<(s++foldr(z(:))e s)

Experimente online! Usa a transposição mais curta que encontrei há um tempo.

Explicação

eé uma lista infinita de listas vazias e usada para a transposição. zé uma abreviação para a zipWithfunção, porque é usada duas vezes.

f s=                                        -- input s is a list of lists
                            foldr(z(:))e s  -- transpose s
                         s++                -- append the result to the original list s
                     =<<(                 ) -- map the following function over the list and concatenate the results
        (z(-)=<<tail)                       -- compute the delta of each list by element-wise subtracting its tail
    sum$                                    -- compute the sum of the resulting list
Laikoni
fonte
3

Braquilog , 13 bytes

orignally baseado no design de @ sundar

⟨≡⟨t-h⟩ᵐ²\⟩c+ 

Explicação

⟨≡      \⟩          #   Take the original matrix and it's transpose 
      ᵐ             #       and execute the following on both
       ²            #           map for each row (this is now a double map "ᵐ²")
  ⟨t h⟩             #               take head and tail
   -                #               and subtract them from each other (sum of deltas in a row)
         c+         #       and add all the values 
                    #           (we have two arrays of arrays so we concat them and sum them)

o ⟨⟩estão atrapalhando a formatação, desculpe

Experimente online!

Kroppeb
fonte
2

Pitão, 7 bytes

ss.+M+C

Experimente aqui.

Minha primeira resposta em um idioma de golfe! Obrigado a @EriktheOutgolfer por -1 byte!

Explicação

ss.+M+C    ~ This is a full program with implicit input (used twice, in fact)

      C    ~ Matrix transpose. Push all the columns;
     +     ~ Concatenate with the rows;
  .+M      ~ For each list;
  .+       ~ Get the deltas;
 s         ~ Flatten the list of deltas;
s          ~ Get the sum;
           ~ Print Implicitly;
Mr. Xcoder
fonte
.tpode ser Cpara -1.
Erik the Outgolfer
@EriktheOutgolfer Oh uau, obrigado!
2

Braquilog , 22 16 bytes

⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ

Experimente online!

(-6 bytes inspirado nas sugestões de @ Kroppeb.)

?⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ.       Full code (? and . are implicit input and output)
?⟨≡{       }ᵐ\⟩          Apply this on both the input and its transpose:
    s₂ᶠ                  Get pairs of successive rows, [[row1, row2], [row2, row3], ...]
       c                 Flatten that: [row1, row2, row2, row3, row3, row4, ...]
        +ᵐ               Sum the elements within each row [sum1, sum2, sum2, sum3, ...]
          -              Get the difference between even-indexed elements (starting index 0)
                         and odd-indexed elements, i.e. sum1+sum2+sum3+... - (sum2+sum3+sum4+...)
                         This gets the negative of the usual difference i.e. a-b instead of b-a
                         for each pair of rows
               +         Add the results for the input and its transpose
                ṅ        Negate that to get the sign correct
                 .       That is the output
sundar - Restabelecer Monica
fonte
A soma dos deltas é igual ao último elemento - o primeiro ⟨t-h⟩faz o truque. Resultando em {⟨t-h⟩ᵐ+}R&\↰₁;R+que é 5 bytes mais curto. Experimente online!
Kroppeb
usando em ⟨≡{...}ᵐ\⟩+vez de {...}R&\↰₁;R+salva 2 bytes. Resultando em ⟨≡{⟨t-h⟩ᵐ+}ᵐ\⟩+ Experimente online!
precisa saber é o seguinte
Alterar o mapeamento de um mapa em um mapa duplo e concatenar e soar no e remove 2 bytes adicionais ⟨≡⟨t-h⟩ᵐ²\⟩c+. Experimente online!
precisa saber é
@ Kroppeb Isso é bastante diferente e grande o suficiente para uma melhoria, e você deve publicá-la como uma nova resposta. Ver suas sugestões me deu uma idéia para uma solução de 16 bytes usando um método diferente ⟨≡{s₂ᶠc+ᵐ-}ᵐ\⟩+ṅ Experimente on-line! , então atualizarei esta resposta com essa versão.
sundar - Restabelece Monica
2

Japonês -x , 11 10 9 bytes

cUy)®än x

Tente


Explicação

c             :Concatenate
 U            :  Input array
  y           :  Transpose
   )          :End concatenation
    ®         :Map
     än       :  Deltas
        x     :  Reduce by addition
              :Implicitly reduce by addition and output
Shaggy
fonte
1

SOGL V0.12 , 9 bytes

:⌡-≤H⌡-¹∑

Experimente aqui!( adicionado porque isso recebe entrada na pilha)

Explicação:

:          duplicate ToS
 ⌡         for each do
  -          get deltas
   ≤       get the duplicate ontop
    H      rotate it anti-clockwise
     ⌡     for each do
      -      get deltas
       ¹   wrap all of that in an array
        ∑  sum
dzaima
fonte
11
adicionado porque isso leva a entrada na pilha - estou pensando em perguntar isso há muito tempo: A entrada é enviada automaticamente para a pilha? Se não estiver, e espera que a entrada já esteja presente na pilha, você também não deve adicionar sua contagem de bytes? Não tenho certeza de como essas situações são tratadas. Ou é como uma função?
Xcoder 10/09
@ Mr.Xcoder hmm .. Eu pensei que isso era permitido pelas entradas padrão, mas acho que só existe isso para funções. Então, novamente, eu poderia chamar isso de uma função sem nome usada como esta (em SOGL, a definição de "função" é functionNameSingleChar\n)
dzaima 10/09
Ah, tudo bem. É perfeitamente válido então.
Sr. Xcoder 10/09
1

Mathematica, 45 bytes

Tr@Flatten[Differences/@#&/@{#,Transpose@#}]&

Entrada

[{{13, 19, 478}, {0, 12, 4}, {45, 3, 6}, {1, 2, 3}}]

J42161217
fonte
Seria mais curto subtrair o primeiro do último para cada array {#,Transpose@#}(como minha resposta em Python)?
Jonathan Allan
Total[Differences/@{#,Thread@#},3]&
alephalpha
1

CJam , 19 bytes

0q~_z+2few:::-:+:+-

Entrada é uma lista de listas de números. Experimente online!

Explicação

0       e# Push 0
q~      e# Evaluated input. 
_       e# Duplicate
z       e# Zip (transpose)
+       e# Concatenate. This gives a lists of lists of numbers, where the
        e# inner lists are the original rows and the columns
2few    e# Replace each inner list of numbers by a list of overlapping
        e# slices of size 2. We not have three-level list nesting
:::-    e# Compute difference for each of those size-two slices. We now
        e# have the deltas for each row and column
:+      e# Concatenate all second-level lists (de-nest one level)
:+      e# Sum all values
-       e# Subtract from 0, to change sign. Implicitly display
Luis Mendo
fonte
4
Esta resposta precisa de mais dois pontos. Existem 2fewdois pontos.
Esolanging Fruit
0

MEU, 9 bytes

ωΔω⍉Δ ḟΣ↵

Experimente online!

Como não consigo executar ping no Dennis no chat para obter o MY (devido a uma suspensão), isso não funcionará no momento. ( Δantes não vecificava ao subtrair) Obrigado a quem conseguiu Dennis puxar MEU!

Quão?

  • ωΔ, incrementos do primeiro argumento da linha de comandos
  • ω⍉Δ, incrementos da transposição do primeiro argumento da linha de comandos
  • , em uma única lista
  • achatar
  • Σsoma
  • , resultado
Zacharý
fonte
0

Pyt , 11 bytes

Đ⊤ʁ-⇹ʁ-áƑƩ~

Explicação:

          Implicit input (as a matrix)
Đ         Duplicate the matrix
⊤         Transpose the matrix
ʁ-        Get row deltas of transposed matrix
⇹         Swap top two elements on the stack
ʁ-        Get row deltas of original matrix
á         Push the stack into an array
Ƒ         Flatten the array
Ʃ         Sum the array
~         Flip the sign (because the deltas are negative, as subtraction was performed to obtain them)
          Implicit output
mudkip201
fonte