対角線を合計する


19

入力として正の整数の行列を取り、行列を通る対角線上の要素の個々の合計を出力します。

対角線で右下に向かう線のみを数えます。以下に示すように、左下の要素のみを含む対角線から開始し、次にその上の長さ2の対角線(存在する場合)から右上の要素のみを含む対角線まで続けなければなりません。

例:

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

入出力フォーマットは、いつものようにオプションです。

これはなので、各言語での最短の提出が勝ちです。


回答:


6

Haskell40 37バイト

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

オンラインでお試しください!使用法:(foldl1$(.(++z)).zipWith(+).(0:)) [[1,2,3],[4,5,6]]

編集: -3バイトのØrjanJohansenに感謝!

ゴルフをしていない:

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

z無限に多くのゼロのリストです。ではf、私たちは、リストのリストを超える倍m機能を持つ2つのリストを組み合わせることで##最初のリストsこれまでに蓄積された列合計を含み、第二のリストがt追加されるべき新しい行です。s前にゼロを追加し、要素ごとにadd stwith を使用して、1つの要素を右にシフトしzipWith(+)ます。s任意に大きくなる可能性があるため、をt追加して十分なゼロを埋め込む必要がありzます。


それはより短いポイントフリーです:foldl1$(.(++z)).zipWith(+).(0:)
Ørjanヨハンセン

6

Mathematica、53 54バイト

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

入力として2D配列を取り、リストを返す純粋な関数。(エントリは整数または偶数である必要はありません。)メインの対角線の上(または負の場合は下)の対角線をDiagonal[#,k]返します。入力配列の次元に基づいて、必要な対角線の範囲を計算します。そして、各対角線のエントリを合計します。kk{k,-l@#,l@#&@@#}Tr


同じバイト数の代替品ですが、さらにゴルフをすることができますか?これらの括弧は見た目が悪いです。Tr@Diagonal[m,#]&/@Range@@({-1,1}(Dimensions[m=#]-1))&
マーティンエンダー

5

MATL、6バイト

T&XdXs

オンラインでお試しください!または、すべてのテストケースを確認します

説明

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

好奇心が強い:s==sum(x(:))MATLが行うように、MATLABの慣習に固執するのではなく、全体的に持っている方が良いと思いますか?
スティーヴィーグリフィン

@StewieGriffin私は時々それについて考えました。私の疑いは〜の間sum(x)にあったsum(x,1)。行列の場合、行列の行が1行の場合の動作が異なるxという事実sum(x)は、時には迷惑です。しかし、最終的にはMatlabを使用することに決めたため、2つの言語はより密接になりました。fun(x,1)最も一般的な場合にいくつかの機能を追加します
ルイスメンドー

5

ゼリー、5バイト

0;+µ/

オンラインでお試しください!

使い方

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.

削減する最初のRにのみ1つの要素があります。行ごとにもう1要素増加します。
Ørjanヨハンセン

これはただ賢い...いいえŒD
エリックアウトゴルファー

@EriktheOutgolfer繰り返しますが、ŒDの奇妙な順序により、それが有用であることが妨げられました。
デニス

@Dennisそれから、私はそれほど奇妙な順序を持たない何かを作ると思います...ああ、多分3つのモナド入ってくるかもしれません。
エリックアウトゴルファー

5

JavaScript(ES6)、65 58バイト

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

63バイトのバリアント:a=>a.map(r=>r.map(v=>s[i]=~~s[i++]+v,i=--y),s=[],y=a.length)&&s
Arnauld

@Arnauld私は同意する、逆転は悪い動きだった。しかし、長さをとるのも長すぎます!
ニール

3

CJam22 21バイト

Martin Enderのおかげで1バイト節約

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

スタック上の引数を予期する匿名ブロックで、結果をスタックに残します。

オンラインでお試しください!

使い方

_                   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バイト

Rvy¹gÅ0«NFÁ}})ø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)



1

ゼリー、8 バイト

ŒDS€ṙZL$

オンラインでお試しください!

コードの半分は、結果を正しい順序にするために使用されます。

どうやって?

Œ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

R、45バイト

入力として行列クラスオブジェクトをとる名前のない関数:

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

この回答で説明されているアイデアを使用し ます。


このチャレンジのルールにより、への呼び出しを取り除くことができると信じていますunnameが、これは素晴らしいソリューションです!
ジュゼッペ

1

オクターブ、71バイト

Aが行列であると仮定すると、たとえば:

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

それから私達にあります:

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

行列を転置すると、対角和の順序が逆になり、forループで2バイト全体が節約されることに注意してください。

出力:

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,:)),end6バイト節約します。Octaveは、直接インデックス付けとインライン割り当てを行うことができます。残念ながら、コードを実行する前にワークスペースに変数が存在すると仮定することは許可されていないためinputこのように75バイトまで戻す必要があると思います。いいアプローチだから、+ 1してくれたから:)そして、PPCGへようこそ!=)
Stewie Griffin

また、4バイトを節約してzeros(m-1,m)書くことができ~e(m-1,m)ます:)きちんとした?
スティーヴィーグリフィン

0

Python、126バイト

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

f下三角セクションでのみ動作するため、転置して上三角セクションをそのまま取得します。f関数が負の値に対して機能しない理由がわからない(負の値fを取得する部分が機能しなかったため、短くなるように変更しました)。


最後のテストケースでエラーが発生します。tio.run/nexus/…–
デニス

0

C、148バイト

オンラインで試す

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バイト

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

ゴルフをしていない:

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

Awkの空白$nでの分割は、nthフィールド(1から始まる)です。NFは行のフィールドNRの数であり、現在の行の数です。未定義の変数は0で、最初の使用時に作成されます。


0

PHP、86バイト

2つのバリアントのメモリフレンドリーなソリューション:

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

スクリプトパラメータから入力を受け取り、アンダースコアを区切り文字として使用します。
デフォルトの設定(デフォルトのphp.iniではありません)を使用するか、オンラインで試してください


0

Clojure、81バイト

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

リストをゼロで埋めて、列ごとの合計を計算できるようにするため、かなり冗長です。


0

数学73バイト

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

これは、任意の2D配列mxn(nxnだけでなく)
に対して機能します。このようなコードの最後に配列を入力します(最後のテストケース)

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

フォーム[{a、b、c、d ...}、{m、n}]の入力

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.