Somma le diagonali


19

Prendi una matrice di numeri interi positivi come input e genera le singole somme degli elementi sulle linee diagonali attraverso la matrice.

Conterai solo le linee che vanno in diagonale verso il basso e verso destra. Devi iniziare con la diagonale che contiene solo l'elemento in basso a sinistra, quindi la diagonale lunghezza due sopra quella (se esiste) e così via fino alla diagonale che contiene solo l'elemento in alto a destra, come illustrato di seguito.

Esempio:

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

I formati di input e output sono opzionali come sempre.

Si tratta di , quindi vince l'invio più breve in ogni lingua.


Risposte:


6

Haskell , 40 37 byte

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

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

Modifica: grazie a Ørjan Johansen per -3 byte!

Ungolfed:

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

zè un elenco di infiniti zeri. In fpieghiamo l'elenco delle liste mcombinando due liste con la funzione #. Nel #primo elenco scontiene le somme di colonna accumulate finora e il secondo elenco tè la nuova riga che dovrebbe essere aggiunta. Spostiamo sun elemento a destra aggiungendo uno zero sul davanti e elemento saggio aggiuntivo se tcon zipWith(+). Perché spotrebbe essere arbitrariamente grande, dobbiamo taggiungere abbastanza zeri aggiungendo z.


Questo è il più corto-point gratuito: foldl1$(.(++z)).zipWith(+).(0:).
Ørjan Johansen,

6

Mathematica, 53 54 byte

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

Funzione pura che prende un array 2D come input e restituisce un elenco. (Le voci non devono essere numeri interi o numeri pari.) Diagonal[#,k]Restituisce la kdiagonale sopra (o sotto, se kè negativa) la diagonale principale. {k,-l@#,l@#&@@#}calcola l'intervallo di diagonali necessarie in base alle dimensioni dell'array di input. E Trsomma le voci di ogni diagonale.


Alternativa con lo stesso numero di byte, ma forse puoi golf ulteriormente? Quelle parentesi sembrano brutte. Tr@Diagonal[m,#]&/@Range@@({-1,1}(Dimensions[m=#]-1))&
Martin Ender,

5

MATL , 6 byte

T&XdXs

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

T&Xd   % All diagonals of implicit input arranged as zero-padded columns
Xs     % Sum of each column. Implicitly display

Solo curioso: pensi che sarebbe meglio nel complesso avere s==sum(x(:)), invece di attenersi alla convenzione MATLAB, come sembra fare MATL?
Stewie Griffin,

@StewieGriffin A volte ci ho pensato. Il mio dubbio era più tra sum(x)e sum(x,1). Per una matrice x, il fatto che sum(x)si comporti in modo diverso se la matrice ha 1 riga a volte è fastidioso. Ma alla fine ho deciso di andare con Matlab, quindi le due lingue sono più vicine; e aggiungere alcune fun(x,1)funzioni per i casi più comuni
Luis Mendo,

5

Gelatina , 5 byte

0;+µ/

Provalo online!

Come funziona

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.

Solo la prima R da ridurre ha un elemento in meno; aumenta di un altro elemento ogni riga.
Ørjan Johansen,

Questo è solo intelligente ... no ŒD?
Erik the Outgolfer,

@EriktheOutgolfer Ancora una volta, lo ŒDstrano ordinamento gli ha impedito di essere utile.
Dennis,

@Dennis Quindi penso che farei qualcosa che non ha un ordine così strano ... oh, forse 3 monadi potrebbero essere in arrivo.
Erik the Outgolfer,

5

JavaScript (ES6), 65 58 byte

a=>a.map(b=>b.map((c,i)=>r[i]=~~r[i]+c,r=[,...r]),r=[])&&r

Variante 63 byte:a=>a.map(r=>r.map(v=>s[i]=~~s[i++]+v,i=--y),s=[],y=a.length)&&s
Arnauld

@Sono d'accordo, invertire è stata una mossa sbagliata. Ma prendere la lunghezza è troppo lungo!
Neil,

3

CJam , 22 21 byte

Salvato 1 byte grazie a Martin Ender

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

Blocco anonimo che prevede l'argomento nello stack e lascia il risultato nello stack.

Provalo online!

Come funziona

_                   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

2

05AB1E , 17 byte

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

Provalo online!

Spiegazione

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)

2

J , 7 byte

+//.@|.

Provalo online!

Questo è abbastanza semplice:

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

Le linee invertite oblique sono le diagonali dell'array, quindi questo sta semplicemente sommando le diagonali.



1

Gelatina , 8 byte

ŒDS€ṙZL$

Provalo online!

La metà del codice viene utilizzata per mettere i risultati nell'ordine corretto.

Come?

Œ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

1

Perl 5, 47 byte

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

1

R, 45 byte

Funzione senza nome che accetta come input un oggetto di classe matrice:

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

Usando l'idea spiegata in questa risposta.


Credo che le regole di questa sfida ti consentano di sbarazzarti della chiamata unname, ma questa è comunque una soluzione fantastica!
Giuseppe,

1

Ottava, 71 byte

Supponendo che A sia una matrice, ad esempio:

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

Poi abbiamo:

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

Si noti che il recepimento della matrice inverte l'ordine delle somme diagonali, che ha salvato un totale di due byte nel ciclo for.

Produzione:

ans =  24
ans =  29
ans =  22
ans =  39
ans =  47
ans =  70
ans =  43
ans =  9
ans =  5

1
[m,n]=size(A);for i=1:m+n-1,trace([zeros(m-1,m);A'](i:end,:)),endsalva 6 byte. Octave può eseguire indicizzazioni dirette e assegnazioni in linea. Sfortunatamente, supponendo che esista una variabile nello spazio di lavoro prima dell'esecuzione del codice non è consentito, quindi penso che tu debba usarlo input, in questo modo riportandolo a 75 byte. Bel approccio però, quindi +1 da parte mia :) E benvenuto in PPCG! =)
Stewie Griffin

Inoltre, zeros(m-1,m)può essere scritto ~e(m-1,m), salvando 4 byte :) Bene eh?
Stewie Griffin,

0

Python, 126 byte

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

fFunziona solo sulla sezione triangolare inferiore, quindi la traspongo e ottengo la sezione triangolare superiore in quel modo. Non so perché la ffunzione non funziona per valori negativi (ho cambiato fper essere più breve perché la parte per ottenere i negativi non ha funzionato).


Viene visualizzato un errore per l'ultimo caso di test. tio.run/nexus/…
Dennis,

0

C, 148 byte

Prova online

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);}


0

Awk, 67 byte

{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]
}

Awk si divide nello spazio bianco $nè il ncampo th (1-indicizzato); NFè il numero di campi sulla riga, NRè il numero della riga corrente. Le variabili non definite sono 0 e create al primo utilizzo.


0

PHP, 86 byte

una soluzione adatta alla memoria in due varianti:

<?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++];

accetta input dai parametri dello script, usa il trattino basso come delimitatore;
usa le impostazioni predefinite (non predefinite php.ini) o provale online


0

Clojure, 81 byte

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

Abbastanza dettagliato, poiché riempie gli elenchi con zeri in modo che possiamo semplicemente calcolare la somma per colonna.


0

matematica 73 byte

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

Questo funziona per QUALSIASI mxn di array 2D (non solo nxn)
immette l'array alla fine del codice in questo modo (l'ultimo caso di test)

[{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}

input in forma [{a, b, c, d ...}, {m, n}]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.