各次元の合計


20

整数の多次元配列が与えられます。各次元のサイズは固定です(2Dの場合は常に長方形になります)。プログラムは、各ディメンションの合計を計算し、そのディメンションの新しい最後のアイテムとして合計を追加する必要があります。

入力配列と出力配列がAとBであり、A の次元iのサイズがn iであると仮定します。BはAと同じ次元数を持ち、次元iのサイズはn i +1になります。B j 1、j 2、...、j mは、A k 1、k 2、...、k mの合計です。ここ

  • kはiは J = iが jの場合、I <= N Iを
  • 0 <k i <= n i j i = n i +1の場合

入力用:

[[1 2 3]
 [4 5 6]]

プログラム(または関数)が出力するはずです:

[[1 2 3 6]
 [4 5 6 15]
 [5 7 9 21]]

入力には配列のみが含まれます。次元の合計数と各次元のサイズは、入力に含まれていません。(ただし、独自のコードで配列から取得できます。)次元数または次元サイズを直接指定しない限り、言語で便利なリスト形式を使用できます。

入力には少なくとも1つの次元があり、配列には少なくとも1つの項目があります。

これはコードゴルフです。最短のコードが優先されます。

テストケース

Input:
[5 2 3]
Output:
[5 2 3 10]

Input:
[[1 2 3] [4 5 6]]
Outputs:
[[1 2 3 6] [4 5 6 15] [5 7 9 21]]

Input:
[[[1] [1] [1] [0]]]
Output:
[[[1 1] [1 1] [1 1] [0 0] [3 3]] [[1 1] [1 1] [1 1] [0 0] [3 3]]]

Input:
[[[[-1]]]]
Output:
[[[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]] [[[-1 -1] [-1 -1]] [[-1 -1] [-1 -1]]]]

16バイトのAPLソリューションを投稿しますか?そうでない場合、私はできますか?
デニス

@Dennis投稿してください。
jimmy23013

回答:


9

J、14バイト

#@$(0|:],+/^:)

使用法:

   ]a=.i.2 3
0 1 2
3 4 5

   (#@$(0|:],+/^:)) a    NB. parens are optional
0 1 2  3
3 4 5 12
3 5 7 15

この関数は以下と同等です(0|:],+/)^:(#@$)が、ユーザー定義の副詞を使用して括弧を保存します。

右から左への後者のコードの説明:

  • ^:(#@$)次元^:の数だけ繰り返し#ます$

    • ],+/最後の次元での合計で,引数に連結します]+/
    • 0|:|:最初0のディメンションをディメンションリストの最後に追加して、ディメンションを回転させます
  • 上記の手順を実行した後、すべてのディメンションの合計を含む元の入力を取得します。

古いソリューションについては、改訂履歴を確認してください。

こちらからオンラインでお試しください。


15

Mathematica、32 20バイト

#/.List->({##,+##}&)&

例:

In[1]:= #/.List->({##,+##}&)&[{{1, 2, 3}, {4, 5, 6}}]

Out[1]= {{1, 2, 3, 6}, {4, 5, 6, 15}, {5, 7, 9, 21}}

説明:

の完全な形式は{{1, 2, 3}, {4, 5, 6}}ですList[List[1, 2, 3], List[4, 5, 6]]。次にList、式のすべてのsを関数で置き換えます({##,+##}&)


10

Python 2、95バイト

from numpy import*
a=copy(input())
for d in r_[:a.ndim]:a=r_[`d`,a,sum(a,d,keepdims=1)]
print a

これは各ディメンションを反復処理し、NumPyを使用して合計を連結します。

NumPy's r_に出くわしましたが、これはゴルフにはとても素晴らしいものです。r_[:n]より短くrange(n)、はるかに強力です(例r_[:4, 7, 8, 10:100:10])。また、任意の軸に沿った連結のような他のこともできます。

使用例:

$ python sum.py
[[1, 2, 3], [4, 5, 6]]
[[ 1  2  3  6]
 [ 4  5  6 15]
 [ 5  7  9 21]]

7

APL、16 15バイト

{×≡⍵:∇¨⍵,+/⍵⋄⍵}

@ user23013に3バイトをゴルフして、適切な入力フォーマットを見つけてくれてありがとう。

TryAPLを使用して、オンラインでテストケースを検証します

アイディア

一般的な考え方はCJamの提出と同じで、APLを使用するとはるかに短い実装が可能になります。次の2つのステップのみで構成されます。

  1. 一番外側の次元で配列を合計します。

  2. サブアレイごとに手順1を繰り返します。

コード

{             } ⍝ Define a monadic function with argument ⍵ and reference ∇.
 ×≡⍵:           ⍝ If the depth of ⍵ is positive:
     ∇          ⍝   Apply this function...
      ¨         ⍝   to each element of...
       ⍵,       ⍝   the concatenation of ⍵...
         +/⍵    ⍝   and the sum across ⍵.
            ⋄⍵  ⍝  Else, return ⍵.

元のコードの入力形式を把握しました:,⊂(,1)(,1)(,1)(,0)および,⊂,⊂,⊂,¯1それぞれ。そのため、別のキャラクターを削除できます。
jimmy23013

2
@ user23013:だから私のコードはうまくいきました!あなたは...入力フォーマットは、右の実際のコードより取得することはより困難であるプログラミング言語を好きに持っている
デニス

6

ピップ18 15バイト

{a-a?fMaAE$+aa}

これは、引数として配列を取り、結果を返す匿名関数です。-pフラグを使用して読み取り可能な出力を取得するサンプル呼び出し:

C:\> pip.py -pe "( {a-a?fMaAE$+aa} [[1 2 3] [4 5 6]] )"
[[1;2;3;6];[4;5;6;15];[5;7;9;21]]

アイデアは基本的にデニスのAPLと同じですが、独立して派生しています。すなわち:

{             }  Define a lambda function with parameter a
 a-a?            Shortest way I could find to test whether the argument is a list
                 or scalar: subtracting a number from itself gives 0 (falsy);
                 subtracting a list from itself gives a list of zeros (truthy!)
     fM          If truthy, it's a list, so map the same function (f) recursively to:
       aAE         Argument, with appended element...
          $+a      ...sum of argument (fold on +)
             a   If falsy, it's a scalar, so just return it

この方法が機能するのは、+(他の多くの演算子とともに)Pipのリストで項目ごとに機能するためです。これは、APLのような配列プログラミング言語からヒントを得た機能です。したがって、の$+ようなリストの場合[[1 2 3] [4 5 6]]、結果は[5 7 9]望みどおりです。リストまたはスカラーテストでも使用されます:[1 2 3] - [1 2 3]gives [0 0 0]、これは真実です(空のリストを除くすべてのリストと同様)。

以前の18バイトバージョン:

{Ja=a?a(fMaAE$+a)}

変更点:

  1. スカラーまたはリストテストでバイトを保存しました。以前の方法は、引数を結合し(空の文字列で)、その結合されていないselfと等しいかどうかをテストすること[1 2 3] != 123でした(ため、動作します)。
  2. 括弧を削除しました。彼らは、元のためにいる必要はMより低い優先順位である?(私はおそらく特に今、それを変更するつもりですが):それらなしで、コードはように解析しまう(Ja=a?af)M(aAE$+a)奇妙なエラーメッセージにつながります。しかし、三項演算子の中間の引数が可能任意のどんな優先の発現、何の括弧は必要ありません。したがって、リストを真実のケースにすることで、これらの2バイトを節約できます。

2
それはあなたがそこに着いた面白い言語です。アイテムごとの演算子は、CJamとPythに欠けているものです。
デニス

@デニスありがとう!まだ進行中の作業ですが、いくつかのタスクがあります。
DLosc

5

APL(25)

{N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵}

APLの配列には次元が組み込まれているため、これはn次元の配列を取り、各次元に沿って合計する関数です。

      {N⊣{N,[⍵]←+/[⍵]N}¨⍳⍴⍴N←⍵} ↑(1 2 3)(4 5 6)
1 2 3  6
4 5 6 15
5 7 9 21

説明:

  • N←⍵:配列をに保存しNます。
  • ⍴⍴N:寸法の量を取得しNます。(すなわち、大きさを与える⍴↑(1 2 3)(4 5 6)与える2 3ので、⍴⍴寸法の大きさを与えます。)
  • {... }¨⍳:1までの各数値について⍴⍴N
    • +/[⍵]NN次元に沿った合計
    • N,[⍵]←:結果をNそのディメンションに結合します
  • N:最後に、戻りNます。

配列にシングルトンが含まれている場合、これを機能させることはできません。3番目または4番目のテストケースでこの関数をどのように呼び出しますか?
デニス

3
@Dennis:関数に多次元配列を渡す必要があります。何↑(1 2 3)(4 5 6)やっていることは、単に使用して2 1次元のものから2次元配列を構築しています。それは組み込みの表記法ではなく、あなたが考えるかもしれない方法を一般化しません。3番目と4番目の配列を構築する標準的な方法は1 4 1⍴1 1 1 0and 1 1 1 1⍴¯1ですが、サイズを参照せずに構築することもできます。たとえば、3番目の配列はで構築↑⍉⍪(,1)(,1)(,1)(,0)でき、4番目は4で構築できます↑⍪⊂⍪¯1
マリヌス

OK、それはすべてを説明します。再帰的なアプローチの私のナイーブな実装では、私が(例えば配列と思っていたもののためにうまく機能f←{0=≡⍵:⍵⋄f¨⍵,+/⍵}⋄f((1 2)(3 4))((5 6)(7 8)))が、ネストされたベクトルと配列が異なっているようだし、前者は...シングルトンと区別スカラーをしていない
デニス

2
@Dennis Golfed: {×≡⍵:∇¨⍵,+/⍵⋄⍵}((1 2)(3 4))((5 6)(7 8))。修正済み:{×⍴⍴⍵:∇↓⍵,+/⍵⋄⍵}1 4 1⍴1 1 1 0。それは...今のMathematicaよりも短いです
jimmy23013

3

CJam、36バイト

{_`{'[<}#:D{_":"D'.e]'++~a+{S}%}&}:S

これは、スタックから配列をポップし、1つの配列を返す、名前付きの再帰関数です。

CJamインタープリターでテストケースを試してください。

アイディア

残念ながら、CJamには任意にネストされた配列を追加できる自動演算子がないため、自分で実装する必要があります。幸いなことに、このタスクに役立つ証明となる2つの中置演算子:(reduce)と.(vectorize)を実行します。

ステップ1は、次元数の計算です。これは簡単です。配列を文字列表現に変換し、先頭の[の数を数えます。

さて、1次元の配列を減らすために、通常は次を実行し:+ます:

[1 2] :+ e# Pushes 3.

2次元の配列の場合、+加算ではなく連結を実行するため、ベクトル化する必要があります。

[[1 2][3 4]] :.+ Pushes [4 6].

ここで、3次元の.+配列の場合、2次元の配列を操作し、再度連結を実行します。今回は、ベクトル化する必要があります.+

[[[1 2][3 4]][[5 6][7 8]]] :..+ e# Pushes [[[6 8] [10 12]]].

一般的な場合、次元Dの配列、1つを連鎖する必要があります: D-1 .および1つあり+ます。

もちろん、これは配列をその最外の次元でのみ合計するだけです。これを解決するには、次元を計算し(ゼロの場合は何もしない)、上記のように合計を実行し、最後に配列の要素に適用する関数Sを定義します。

コード

{                                }:S e# Define S:
 _`                                  e#   Push a string representation of a the array.
   {'[<}#                            e#   Find the index of the first non-bracket.
         :D                          e#   Save it in D.
           {                   }&    e#   If D is positive:
            _                        e#     Push a copy of the array.
             ":"D'.e]                e#     Pad ":" with "."s to a string of length D.
                     '++~            e#     Add a "+" to the string and evaluate.
                         a+          e#     Wrap the result in a array and concatenate.
                           {S}%      e#     Apply S to the elements of the array.

2

ルビー(181 139 119 108バイト)

def d a;a.push a[0].to_s['[']?a.map{|x|d x}.transpose.map{|x|x.reduce:+}:a.reduce(:+)end
p d eval ARGF.read

入力がJSONとして渡されると仮定します。


実際、解析された配列を受け入れて配列を返す関数を作成するだけでd、この回答では95バイトしかカウントできません。
jimmy23013

2

Java、669バイト

嘘をつくつもりはありません、私はこれについて自分自身を非常に誇りに思っています:p

import java.lang.reflect.Array;enum S{D;<A>A s(A a){int l=Array.getLength(a),x=0;Class t=a.getClass();Class c=t.getComponentType();A r=(A)Array.newInstance(c,l+1);System.arraycopy(a,0,r,0,l);if(t==int[].class)for(;x<l;)((int[])r)[l]=((int[])r)[l]+((int[])r)[x++];else{for(;x<l;)Array.set(r,x,S.this.s(Array.get(r,x++)));Object o=Array.get(r,0);for(;--x>0;)o=s(o,Array.get(r,x));Array.set(r,l,o);}return r;}<A>A s(A a,A b){int l=Array.getLength(a),x=0;Class t=a.getClass();A r=(A)Array.newInstance(t.getComponentType(),l);if(int[].class==t)for(;x<l;)((int[])r)[x]=((int[])a)[x]+((int[])b)[x++];else for(;x<l;)Array.set(r,x,s(Array.get(a,x),Array.get(b,x++)));return r;}}

テストで拡張:

import java.lang.reflect.Array;
import java.util.Arrays;

public enum SumOf{
    Dimensions;

    <A>A sum(A array){ //call this method to solve the challenge
        int length=Array.getLength(array),x=0;
        Class arrayType=array.getClass();
        Class componentType=arrayType.getComponentType();
        //grow the array to include the sum element
        A result=(A)Array.newInstance(componentType,length+1);
        System.arraycopy(array,0,result,0,length);
        if(arrayType==int[].class) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum
                ((int[])result)[length]=((int[])result)[length]+((int[])result)[x++];        
        else{ //multi-dimensional array
            for(;x<length;) //find the sum for each element in this dimension's array
                Array.set(result,x,sum(Array.get(result,x++)));
            //find the total sum for this dimension's array
            Object s=Array.get(result,0);
            for(;--x>0;)
                s=_sum(s,Array.get(result,x)); //add the 2 elements together
            Array.set(result,length,s);
        }
        return result;
    }

    <A>A _sum(A arrayA,A arrayB){ //this method is used by the previous method
        int length=Array.getLength(arrayA),x=0;
        Class arrayType=arrayA.getClass();
        A result=(A)Array.newInstance(arrayType.getComponentType(),length);
        if(int[].class==arrayType) //one-dimensional array needs to be handled separately
            for(;x<length;) //find the sum of both arrays
                ((int[])result)[x]=((int[])arrayA)[x]+((int[])arrayB)[x++];
        else
            for(;x<length;) //find the sum of both arrays
                Array.set(result,x,sum(Array.get(arrayA,x),Array.get(arrayB,x++)));
            return result;
        }

    static int[] intArray( int firstElement, int...array ) {
        if( array == null ) array = new int[0];
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static <E> E[] arrayArray( E firstElement, E...array ) {
        if( array == null ) array = (E[]) Array.newInstance( firstElement.getClass(), 0 );
        array = Arrays.copyOf( array, array.length + 1 );
        System.arraycopy( array, 0, array, 1, array.length - 1 );
        array[0] = firstElement;
        return array;
    }

    static void printIntArray( int[]array ){
        System.out.print("[ ");
        for( int x = 0; x < array.length; x++ )
            System.out.print( array[x] + " " );
        System.out.print("] ");
    }

    static < A > void printArray( A array ) {
        if( array.getClass() == int[].class ){
            printIntArray( (int[]) array );
        }
        else {
            System.out.print("[ ");
            int length = Array.getLength( array );
            for( int x = 0; x < length; x++ )
                printArray( Array.get( array, x ) );
            System.out.print("] ");
        }
    }

    public static void main(String[]s){
        int[] test01 = intArray( 5, 2, 3 );
        System.out.print("Input: ");
        printArray( test01 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test01 ) );
        System.out.println();

        int[][] test02 = arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ) );
        System.out.print("\nInput: ");
        printArray( test02 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test02 ) );
        System.out.println();

        int[][][] test03 = arrayArray( arrayArray( intArray( 1 ), intArray( 1 ), intArray( 1 ), intArray( 0 ) ) );
        System.out.print("\nInput: ");
        printArray( test03 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test03 ) );
        System.out.println();

        int[][][][] test04 = arrayArray( arrayArray( arrayArray( intArray( -1 ) ) ) );
        System.out.print("\nInput: ");
        printArray( test04 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test04 ) );
        System.out.println();

        int[][][] test05 = arrayArray( arrayArray( intArray( 1, 2, 3 ), intArray( 4, 5, 6 ), intArray( 7, 8, 9 ) ), arrayArray( intArray( 11, 12, 13 ), intArray( 14, 15, 16 ), intArray( 17, 18, 19 ) ), arrayArray( intArray( 21, 22, 23 ), intArray( 24, 25, 26 ), intArray( 27, 28, 29 ) ) );
        System.out.print("\nInput: ");
        printArray( test05 );
        System.out.print("\nOutput: ");
        printArray( SumOf.Dimensions.sum( test05 ) );
        System.out.println();
    }

}

拡張テストバージョンを実行すると、次のように出力されます。

Input: [ 5 2 3 ] 
Output: [ 5 2 3 10 ] 

Input: [ [ 1 2 3 ] [ 4 5 6 ] ] 
Output: [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 5 7 9 21 ] ] 

Input: [ [ [ 1 ] [ 1 ] [ 1 ] [ 0 ] ] ] 
Output: [ [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] [ [ 1 1 ] [ 1 1 ] [ 1 1 ] [ 0 0 ] [ 3 3 ] ] ] 

Input: [ [ [ [ -1 ] ] ] ] 
Output: [ [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] [ [ [ -1 -1 ] [ -1 -1 ] ] [ [ -1 -1 ] [ -1 -1 ] ] ] ] 

Input: [ [ [ 1 2 3 ] [ 4 5 6 ] [ 7 8 9 ] ] [ [ 11 12 13 ] [ 14 15 16 ] [ 17 18 19 ] ] [ [ 21 22 23 ] [ 24 25 26 ] [ 27 28 29 ] ] ] 
Output: [ [ [ 1 2 3 6 ] [ 4 5 6 15 ] [ 7 8 9 24 ] [ 12 15 18 45 ] ] [ [ 11 12 13 36 ] [ 14 15 16 45 ] [ 17 18 19 54 ] [ 42 45 48 135 ] ] [ [ 21 22 23 66 ] [ 24 25 26 75 ] [ 27 28 29 84 ] [ 72 75 78 225 ] ] [ [ 33 36 39 108 ] [ 42 45 48 135 ] [ 51 54 57 162 ] [ 126 135 144 405 ] ] ] 

拡張バージョンのerm、行:Array.set(result、x、sum(Array.get(arrayA、x)、Array.get(arrayB、x ++))); _sum(...)メソッドでは、sum(...)ではなく、_sum(...)を呼び出す必要があります。私の悪い
ジャック弾薬
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.