Tổng theo từng chiều


20

Bạn được cung cấp một loạt các số nguyên. Mỗi kích thước có một kích thước cố định (sao cho nó luôn luôn là hình chữ nhật nếu là 2D). Chương trình của bạn nên tính toán các khoản tiền theo từng thứ nguyên và nối các khoản tiền dưới dạng các mục cuối cùng mới trong thứ nguyên đó.

Giả sử mảng đầu vào và đầu ra là A và B, và kích thước của chiều i của A là n i . B sẽ có cùng số kích thước với A và kích thước của kích thước i sẽ là n i +1. B j 1 , j 2 , ..., j m là tổng của A k 1 , k 2 , ..., k m trong đó:

  • k i = j i nếu j i <= n i
  • 0 <k i <= n i nếu j i = n i +1

Đối với đầu vào:

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

Chương trình của bạn (hoặc chức năng) sẽ xuất ra:

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

Đầu vào chỉ chứa mảng. Tổng số kích thước và kích thước của mỗi kích thước không được đưa ra trong đầu vào. (Nhưng bạn có thể lấy chúng từ mảng bằng mã của riêng mình.) Bạn có thể sử dụng bất kỳ định dạng danh sách thuận tiện nào trong ngôn ngữ của mình, miễn là nó không chỉ định trực tiếp số lượng kích thước hoặc kích thước kích thước.

Đầu vào có ít nhất 1 thứ nguyên và có ít nhất 1 mục trong mảng.

Đây là mã golf. Mã ngắn nhất sẽ thắng.

Các trường hợp thử nghiệm

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

Bạn sẽ đăng giải pháp APL 16 byte đó chứ? Nếu bạn sẽ không, tôi có thể?
Dennis

@Dennis Bạn nên đăng nó.
jimmy23013

Câu trả lời:


9

J, 14 byte

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

Sử dụng:

   ]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

Hàm này tương đương với các mục sau (0|:],+/)^:(#@$)nhưng sử dụng trạng từ do người dùng xác định để lưu parens.

Giải thích cho mã sau từ phải sang trái:

  • ^:(#@$)lặp lại ^:cho số lượng #kích thước $:

    • ],+/nối ,với đối số ]với tổng của nó trên chiều cuối cùng+/
    • 0|:xoay kích thước |:bằng cách đặt cái đầu tiên 0vào cuối danh sách thứ nguyên
  • Sau khi thực hiện quy trình trên, chúng tôi lấy lại đầu vào ban đầu với tổng trên tất cả các kích thước.

Đối với giải pháp cũ của tôi kiểm tra lịch sử sửa đổi.

Hãy thử trực tuyến tại đây.


15

Toán học, 32 20 byte

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

Thí dụ:

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

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

Giải trình:

Các hình thức đầy đủ {{1, 2, 3}, {4, 5, 6}}List[List[1, 2, 3], List[4, 5, 6]]. Sau đó thay thế tất cả các Lists trong biểu thức bằng hàm ({##,+##}&).


10

Python 2, 95 byte

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

Điều này lặp đi lặp lại theo từng chiều, nối các khoản tiền của nó bằng NumPy.

Tôi tình cờ gặp NumPy r_, một điều khá tuyệt vời khi chơi gôn. r_[:n]ngắn hơn range(n)và mạnh hơn nhiều (ví dụ r_[:4, 7, 8, 10:100:10]). Nó cũng có thể làm những việc khác như ghép dọc theo một trục tùy ý.

Ví dụ sử dụng:

$ 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 byte

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

Cảm ơn @ user23013 vì đã chơi golf 3 byte và tìm ra định dạng đầu vào thích hợp.

Xác minh các trường hợp thử nghiệm trực tuyến với TryAPL .

Ý kiến

Ý tưởng chung giống như trong bản đệ trình CJam của tôi, mà APL cho phép thực hiện ngắn hơn nhiều. Nó chỉ bao gồm hai bước:

  1. Tính tổng các mảng trên kích thước ngoài cùng của nó.

  2. Lặp lại bước 1 cho mỗi phân đoạn.

{             } ⍝ 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 ⍵.

Chỉ cần tìm ra định dạng đầu vào cho mã gốc của bạn: ,⊂(,1)(,1)(,1)(,0),⊂,⊂,⊂,¯1tương ứng. Vì vậy, bạn có thể loại bỏ một nhân vật khác.
jimmy23013

2
@ user23013: Vậy mã của tôi đã hoạt động! Bạn phải yêu thích một ngôn ngữ lập trình trong đó định dạng đầu vào khó lấy đúng hơn mã thực tế ...
Dennis

6

Pip , 18 15 byte

{a-a?fMaAE$+aa}

Đây là một hàm ẩn danh, lấy mảng làm đối số và trả về kết quả. Gọi mẫu, sử dụng -pcờ để có được đầu ra có thể đọc được:

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

Ý tưởng về cơ bản giống như APL của Dennis , mặc dù có nguồn gốc độc lập. Cụ thể hơn:

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

Phương pháp này hoạt động vì +(cùng với nhiều toán tử khác) hoạt động theo từng mục trong danh sách trong Pip - một tính năng được lấy cảm hứng từ các ngôn ngữ lập trình mảng như APL. Vì vậy, khi bạn $+một danh sách như thế [[1 2 3] [4 5 6]], kết quả là [5 7 9]như mong muốn. Cũng được sử dụng trong kiểm tra danh sách hoặc vô hướng: [1 2 3] - [1 2 3]đưa ra [0 0 0], đó là sự thật (như tất cả các danh sách ngoại trừ danh sách trống).

Phiên bản 18 byte trước:

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

Thay đổi:

  1. Đã lưu một byte trong bài kiểm tra vô hướng hoặc danh sách - phương pháp trước đó là tham gia đối số (trên chuỗi trống) và kiểm tra xem có bằng với bản thân chưa tham gia của nó không (hoạt động vì [1 2 3] != 123);
  2. Loại bỏ các dấu ngoặc đơn. Chúng cần thiết trong bản gốc vì Mcó độ ưu tiên thấp hơn ?(mặc dù tôi có thể sẽ thay đổi điều đó, đặc biệt là bây giờ): không có chúng, mã sẽ phân tích thành (Ja=a?af)M(aAE$+a), dẫn đến các thông báo lỗi kỳ quái. Tuy nhiên, đối số giữa của một toán tử ternary có thể là bất kỳ biểu thức của bất kỳ ưu tiên nào, không cần dấu ngoặc đơn. Vì vậy, bằng cách làm cho danh sách trường hợp trung thực, tôi có thể lưu hai byte đó.

2
Đó là một ngôn ngữ thú vị mà bạn có ở đó. Các toán tử theo thứ tự là những gì còn thiếu trong CJam và Pyth.
Dennis

@Dennis Cảm ơn! Đây vẫn là một công việc đang tiến triển, nhưng có một số nhiệm vụ nó thực hiện khá tốt.
DLosc

5

APL (25)

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

Các mảng của APL có các kích thước được tích hợp sẵn, vì vậy đây là một hàm lấy một mảng n chiều và sau đó tính tổng theo từng chiều.

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

Giải trình:

  • N←⍵: lưu trữ mảng trong N.
  • ⍴⍴N: lấy số lượng kích thước Ncó. ( đưa ra kích thước, nghĩa là ⍴↑(1 2 3)(4 5 6)cho 2 3, do đó ⍴⍴cung cấp kích thước của kích thước.)
  • {... }¨⍳: cho mỗi số từ 1 đến ⍴⍴N:
    • +/[⍵]N: tổng Ntheo chiều
    • N,[⍵]←: tham gia kết quả Ntheo chiều đó
  • N: cuối cùng, trở về N.

Tôi dường như không thể làm cho công việc này nếu mảng chứa singletons. Làm thế nào bạn sẽ gọi chức năng này cho trường hợp thử nghiệm thứ ba hoặc thứ tư?
Dennis

3
@Dennis: bạn cần truyền vào hàm một mảng nhiều chiều. Những gì ↑(1 2 3)(4 5 6)đang làm chỉ đơn giản là xây dựng một mảng 2 chiều từ 2 chiều 1 chiều bằng cách sử dụng . Nó không phải là một ký hiệu tích hợp và nó không khái quát theo cách bạn có thể nghĩ. Cách kinh điển để xây dựng thứ 3 và thứ 4 mảng sẽ 1 4 1⍴1 1 1 01 1 1 1⍴¯1, nhưng nó cũng có thể để xây dựng chúng mà không đề cập đến kích cỡ, ví dụ, mảng thứ ba cũng có thể được xây dựng bằng ↑⍉⍪(,1)(,1)(,1)(,0), là thứ tư có thể được xây dựng với ↑⍪⊂⍪¯1.
bến tàu

OK, điều đó giải thích mọi thứ. Việc triển khai phương pháp đệ quy ngây thơ của tôi hoạt động tốt cho những gì tôi nghĩ là mảng (ví dụ f←{0=≡⍵:⍵⋄f¨⍵,+/⍵}⋄f((1 2)(3 4))((5 6)(7 8))), nhưng có vẻ như các vectơ và mảng lồng nhau là khác nhau và trước đây không phân biệt các vô hướng so với singletons ...
Dennis

2
@Dennis Golfed : {×≡⍵:∇¨⍵,+/⍵⋄⍵}((1 2)(3 4))((5 6)(7 8)). Đã sửa : {×⍴⍴⍵:∇↓⍵,+/⍵⋄⍵}1 4 1⍴1 1 1 0. Nó ngắn hơn
Mathicala

3

CJam, 36 byte

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

Đây là một hàm có tên đệ quy bật ra một mảng từ ngăn xếp và trả lại một mảng.

Hãy thử các trường hợp thử nghiệm trong trình thông dịch CJam .

Ý kiến

Đáng buồn thay, CJam không có một số toán tử tự động cho phép thêm các mảng lồng nhau tùy ý, vì vậy chúng tôi phải tự thực hiện nó. May mắn thay, hai toán tử infix, :(giảm) và .(vectorize), sẽ chứng minh hữu ích cho nhiệm vụ này.

Bước một là tính toán số lượng kích thước. Điều này thật dễ dàng: Chuyển đổi mảng thành biểu diễn chuỗi của nó và đếm số lượng hàng đầu [ 's.

Bây giờ, để giảm một mảng của một chiều, bạn thường chỉ cần thực hiện :+:

[1 2] :+ e# Pushes 3.

Đối với một mảng có hai chiều, +sẽ thực hiện nối thay vì cộng, vì vậy chúng ta phải vector hóa nó:

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

Bây giờ, đối với một mảng gồm ba chiều, .+sẽ hoạt động trên các mảng có hai chiều và thực hiện, một lần nữa, nối lại. Lần này, chúng ta phải vector hóa .+:

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

Đối với trường hợp chung, một mảng có kích thước D , chúng ta phải xâu chuỗi một :, D - 1 . và một +.

Tất nhiên, điều này chỉ tính tổng mảng chỉ trên kích thước ngoài cùng của nó. Chúng ta có thể giải quyết điều này bằng cách xác định hàm S tính toán kích thước (và không làm gì nếu nó bằng 0), thực hiện tổng như đã chỉ ra ở trên và cuối cùng, áp dụng chính nó cho các phần tử của mảng.

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

Ruby ( 181 139 119 108 byte)

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

Giả sử đầu vào được thông qua dưới dạng JSON.


Và trong thực tế, bạn chỉ có thể viết một hàm chấp nhận một mảng được phân tích cú pháp và trả về một mảng, và chỉ đếm 95 byte cho dcâu trả lời này.
jimmy23013

2

Java, 669 byte

Sẽ không nói dối, tôi khá tự hào về bản thân mình vì điều này: 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;}}

mở rộng với thử nghiệm:

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

}

chạy phiên bản thử nghiệm mở rộng in điều này:

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 cho phiên bản mở rộng, dòng: Array.set (result, x, sum (Array.get (mảngA, x), Array.get (ArrayB, x ++))); trong phương thức _sum (...) nên được gọi là _sum (...), không phải tổng (...). xấu của tôi
Jack Ammo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.