Soma as diagonais

19

Pegue uma matriz de números inteiros positivos como entrada e faça a saída das somas individuais dos elementos nas linhas diagonais através da matriz.

Você só deve contar as linhas que vão na diagonal para baixo e para a direita. Você deve começar com a diagonal que contém apenas o elemento inferior esquerdo e, em seguida, a diagonal de comprimento dois acima (se existir), e assim por diante até a diagonal que contém apenas o elemento superior direito, conforme ilustrado abaixo.

Exemplo:

Input:
 8   14    5    1
10    5    5    8
 6    6    8   10
15   15    4   11

Output:
15, 21, 20, 32, 29, 13, 1
(Diagonals: {{15},{6,15},{10,6,4},{8,5,8,11},{14,5,10},{5,8},{1}})

Input:
1
Output:
1

Input: 
1 5
Output:
1, 5

Input:
4
1

Output: 
1, 4

Input:
17    4    5
24   16    5
 9   24   10
 1   14   22
 1   21   24
 4    4   17
24   25   17

Output:
24, 29, 22, 39, 47, 70, 43, 9, 5

Os formatos de entrada e saída são opcionais, como sempre.

Isso é , então a submissão mais curta em cada idioma vence.

Stewie Griffin
fonte

Respostas:

6

Haskell , 40 37 bytes

z=0:z
foldl1$(.(++z)).zipWith(+).(0:)

Experimente online! Uso: (foldl1$(.(++z)).zipWith(+).(0:)) [[1,2,3],[4,5,6]].

Edit: Obrigado a Ørjan Johansen por -3 bytes!

Ungolfed:

z = 0:z
s#t = zipWith(+)(0:s)(t++z)
f m = foldl1 (#) m

zé uma lista de infinitos zeros. Em fque dobre a lista de listas matravés da combinação de duas listas com a função #. Na #primeira lista scontém as somas acumuladas da coluna até o momento e a segunda lista té a nova linha que deve ser adicionada. Mudamos sum elemento para a direita, adicionando zero à frente e adicionando se tcom elementos zipWith(+). Como spode ser arbitrariamente grande, precisamos tacrescentar zeros suficientes anexando z.

Laikoni
fonte
Isso é mais curto livre de ponto: foldl1$(.(++z)).zipWith(+).(0:).
Ørjan Johansen
6

Mathematica, 53 54 bytes

l=Length@#-1&;Tr@Diagonal[#,k]~Table~{k,-l@#,l@#&@@#}&

Função pura, tendo um array 2D como entrada e retornando uma lista. (As entradas não precisam ser números inteiros ou pares.) Diagonal[#,k]Retorna a kth diagonal acima (ou abaixo, se kfor negativo) da diagonal principal. {k,-l@#,l@#&@@#}calcula o intervalo de diagonais necessárias com base nas dimensões da matriz de entrada. E Trsoma as entradas de cada diagonal.

Greg Martin
fonte
Alternativa na mesma contagem de bytes, mas talvez você possa jogar ainda mais? Esses parênteses parecem ruins. Tr@Diagonal[m,#]&/@Range@@({-1,1}(Dimensions[m=#]-1))&
Martin Ender
5

MATL , 6 bytes

T&XdXs

Experimente online! Ou verifique todos os casos de teste .

Explicação

T&Xd   % All diagonals of implicit input arranged as zero-padded columns
Xs     % Sum of each column. Implicitly display
Luis Mendo
fonte
Apenas curioso: você acha que seria melhor ter s==sum(x(:)), em vez de seguir a convenção do MATLAB, como o MATL parece fazer?
Stewie Griffin
@ StewieGriffin Às vezes tenho pensado nisso. Minha dúvida era mais entre sum(x)e sum(x,1). Para uma matriz x, o fato de sum(x)se comportar de maneira diferente se a matriz tiver 1 linha é às vezes irritante. Mas no final decidi ir com o Matlab, para que os dois idiomas fiquem mais próximos; e adicione algumas fun(x,1)funções para os casos mais comuns
Luis Mendo
5

Gelatina , 5 bytes

0;+µ/

Experimente online!

Como funciona

0;+µ/  Main link. Argument: M (matrix / array of rows)

   µ   Combine all links to the left into a chain (arity unknown at parse time) and
       begin a new monadic chain.
    /  Reduce M by that chain. This makes the chain dyadic.
       Let's call the arguments of the chain L and R (both flat arrays).
0;         Prepend a 0 to L.
  +        Perform element-wise addition of the result and R.
           When the chain is called for the n-th time, R has n less elements, so
           the last n elements of L won't have matching elements in R and will be
           left unaltered.
Dennis
fonte
Somente o primeiro R a reduzir possui um elemento a menos; aumenta em mais um elemento a cada linha.
Ørjan Johansen
Isso é inteligente ... não ŒD?
Erik the Outgolfer
@EriktheOutgolfer Mais uma vez, ŒDos pedidos estranhos impediram que fosse útil.
Dennis
@ Dennis Então eu acho que faria algo que não tenha pedidos tão estranhos ... ah, talvez 3 mônadas possam estar chegando.
Erik the Outgolfer
5

JavaScript (ES6), 65 58 bytes

a=>a.map(b=>b.map((c,i)=>r[i]=~~r[i]+c,r=[,...r]),r=[])&&r
Neil
fonte
Variante de 63 bytes:a=>a.map(r=>r.map(v=>s[i]=~~s[i++]+v,i=--y),s=[],y=a.length)&&s
Arnauld
@ Arnauld Eu concordo, reverter foi uma má jogada. Mas levar o comprimento também é muito longo!
Neil
3

CJam , 22 21 bytes

Guardado 1 byte graças a Martin Ender

{_,({0\f+}*ee::m<:.+}

Bloco anônimo esperando o argumento na pilha e deixa o resultado na pilha.

Experimente online!

Como funciona

_                   e# Duplicate the matrix
 ,(                 e# Get its length (# of rows) minus 1
   {0\f+}*          e# Prepend that many 0s to each row
          ee        e# Enumerate; map each row to [index, row]
            ::m<    e# Rotate each row left a number of spaces equal to its index
                :.+ e# Sum each column
Gato de negócios
fonte
2

05AB1E , 17 bytes

Rvy¹gÅ0«NFÁ}})øO¨

Experimente online!

Explicação

R                  # reverse input
 v                 # for each N,y (index, item)
  y¹gÅ0«           # pad y with as many zeroes as the number of rows in the input
        NFÁ}       # rotate each row N times right
            })     # wrap the result in a list
              øO   # sum the columns
                ¨  # remove the last element of the resulting list (the padded zeroes)
Emigna
fonte
2

J , 7 bytes

+//.@|.

Experimente online!

Isso é bem simples:

+//.@|.
+/        sum
  /.      on oblique lines
    @|.   on the reversed array

Linhas invertidas oblíquas são as diagonais da matriz, portanto, isso é apenas a soma das diagonais.

Conor O'Brien
fonte
1

Gelatina , 8 bytes

ŒDS€ṙZL$

Experimente online!

Metade do código é usado para colocar os resultados na ordem correta.

Quão?

ŒDS€ṙZL$ - Main link: list of lists of numbers
ŒD       - diagonals (starts with the diagonal containing the top left element,
         -            then the next diagonal to the right, and so on wrapping around)
  S€     - sum €each
       $ - last two links as a monad
     Z   - transpose the matrix
      L  - length (width of the matrix)
    ṙ    - rotate the results left by that amount
Jonathan Allan
fonte
1

Perl 5, 47 bytes

map{$j=--$.;map{@a[$j++]+=$_}split}<>
print"@a"
faubi
fonte
1

R, 45 bytes

Função sem nome, recebendo um objeto de classe matricial como entrada:

function(x)sapply(split(x,col(x)-row(x)),sum)

Usando a ideia explicada nesta resposta.

Billywob
fonte
Acredito que as regras deste desafio permitem que você se livre da chamada unname, mas essa é uma solução incrível, independentemente!
Giuseppe
1

Oitava, 71 bytes

Supondo que A seja uma matriz, por exemplo:

A = [17 4 5;24 16 5; 9 24 10; 1 14 22; 1 21 24; 4 4 17;24 25 17];

Então nós temos:

[m,n]=size(A);
a=[zeros(m,m-1),A]';
for i=1:m+n-1
trace(a(i:end,:))
end

Observe que a transposição da matriz reverte a ordem das somas diagonais, o que salvou um total de dois bytes no loop for.

Resultado:

ans =  24
ans =  29
ans =  22
ans =  39
ans =  47
ans =  70
ans =  43
ans =  9
ans =  5
It Guy
fonte
11
[m,n]=size(A);for i=1:m+n-1,trace([zeros(m-1,m);A'](i:end,:)),endeconomiza 6 bytes. O Octave pode fazer indexação direta e atribuições em linha. Infelizmente, assumindo que a exist variável no espaço de trabalho antes de executar o código não é permitido, então eu acho que você deve usar input, como este trazendo de volta até 75 bytes. Boa abordagem, no entanto, +1 de mim :) E bem-vindo ao PPCG! =)
Stewie Griffin
Além disso, zeros(m-1,m)pode ser escrito ~e(m-1,m), economizando 4 bytes :) Legal né?
Stewie Griffin
0

Python, 126 bytes

x=input()
f=lambda k:[x[i+k][i]for i in range(len(x)-k)]
a=map(f,range(4)[::-1])
x=zip(*x)
print(map(sum,a+map(f,range(1,4))))

fsó funciona na seção triangular inferior, então eu a transponho e obtenho a seção triangular superior dessa maneira. Não sei por que a ffunção não funciona com valores negativos (mudei fpara ser mais curto porque a parte para obter os negativos não funcionou).

HyperNeutrino
fonte
Eu recebo um erro para o último caso de teste. tio.run/nexus/…
Dennis
0

C, 148 bytes

Experimente on-line

s;g(int i,int j,int**m,int x){for(s=0;x;x--)s+=m[i++][j++];printf(" %d",s);}
k;f(int n,int**m){for(k=n;--k;)g(k,0,m,n-k);for(;k<n;k++)g(0,k,m,n-k);}
Khaled.K
fonte
0

PHP, 81 bytes

Aceitar entrada como matriz 2 D

<?foreach($_GET as$k=>$v)foreach($v as$x=>$y)$r[$x-$k]+=$y;ksort($r);print_r($r);

Experimente online!

Jörg Hülsermann
fonte
0

Awk, 67 bytes

{for(f=0;f++<NF;)s[NF-NR+f]+=$f}END{i=0;while(i++<NR*2)print s[i]}

Ungolfed:

{
    for (f = 0; f++ < NF;)
        s[NF-NR+f] += $f
}
END {
    i = 0
    while (i++ < NR*2)
        print s[i]
}

As divisões do awk no espaço em branco $nsão o nth th (indexado a 1); NFé o número de campos na linha, NRé o número da linha atual. Variáveis ​​indefinidas são 0 e criadas no primeiro uso.

Kevin
fonte
0

PHP, 86 bytes

uma solução amiga da memória em duas variantes:

<?for($i=$c=count($a=$_GET);--$i>-$c;print$s._)for($s=0,$d=$c;$d--;)$s+=$a[$i+$d][$d];
<?for($i=$c=count($a=$_GET);--$i>-$c;print$s._)for($s=$d=0;$d<$c;)$s+=$a[$i+$d][$d++];

recebe entrada de parâmetros de script, usa sublinhado como delimitador;
use as configurações padrão (não o php.ini padrão) ou tente online

Titus
fonte
0

Clojure, 81 bytes

#(apply map +(map(fn[i c](concat(repeat(-(count %)i 1)0)c(repeat i 0)))(range)%))

Bastante detalhado, pois reúne listas com zeros para que possamos calcular a soma em colunas.

NikoNyrh
fonte
0

mathematica 73 bytes

Plus@@@Table[Diagonal[Partition[#1,#2[[1]]],k],{k,-#2[[2]]+1,#2[[1]]-1}]&

Este funciona para QUALQUER mxn de matriz 2D (não apenas nxn)
insira a matriz no final do código como este (o último caso de teste)

[{17,4,5,24,16,5,9,24,10,1,14,22,1,21,24,4,4,17,24,25,17},{3,7}]

{24, 29, 22, 39, 47, 70, 43, 9, 5}

entrada no formato [{a, b, c, d ...}, {m, n}]

J42161217
fonte