Her boyuttaki toplam


20

Size çok boyutlu bir tamsayı dizisi verilir. Her boyutun sabit bir boyutu vardır (böylece 2D ise her zaman dikdörtgen olur). Programınız her boyuttaki toplamları hesaplamalı ve toplamları bu boyuttaki son yeni öğeler olarak eklemelidir.

Giriş ve çıkış dizilerinin A ve B olduğunu ve A boyutunun i boyutunun n i olduğunu varsayalım . B, A ile aynı sayıda boyuta sahip olacak ve i boyutunun boyutu n i +1 olacaktır. B j 1 , j 2 , ..., J m, bir toplamıdır k 1 , k 2 , ..., k, m :

  • k i = j i eğer j i <= n i
  • 0 <k i <= n i eğer j i = n i +1

Giriş için:

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

Programınızın (veya fonksiyonunuzun) çıktısı:

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

Giriş yalnızca diziyi içerir. Boyutların sayısı ve her bir boyutun bir boyut değil verilen giriş. (Ancak bunları diziden kendi kodunuzla alabilirsiniz.) Boyutların sayısını veya boyut boyutlarını doğrudan belirtmediği sürece, dilinizde uygun liste biçimlerini kullanabilirsiniz.

Girdinin en az 1 boyutu ve dizide en az 1 öğesi var.

Bu kod golfü. En kısa kod kazanır.

Test senaryoları

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

Bu 16 bayt APL çözümünü gönderecek misiniz? Yapmazsan, yapabilir miyim?
Dennis

@Dennis Göndermelisiniz.
jimmy23013

Yanıtlar:


9

J, 14 bayt

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

Kullanımı:

   ]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

İşlev aşağıdakine eşittir (0|:],+/)^:(#@$) ancak parenleri kaydetmek için kullanıcı tanımlı bir zarf kullanır.

İkinci kodun sağdan sola açıklaması:

  • ^:(#@$)boyut ^:sayısı için tekrarlayın#$ :

    • ],+/,tartışmayı birleştirmek] son boyuttaki toplamıyla+/
    • 0|:|:ilki 0boyut listesinin sonuna koyarak boyutları döndürme
  • Yukarıdaki prosedürü yaptıktan sonra, orijinal boyutu tüm boyutlarda toplamlarla geri alıyoruz.

Eski çözümüm için düzeltme geçmişini kontrol edin.

Burada çevrimiçi deneyin.


15

Mathematica, 32 20 bayt

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

Örnek:

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

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

Açıklama:

Tam form {{1, 2, 3}, {4, 5, 6}}olduğunu List[List[1, 2, 3], List[4, 5, 6]]. Sonra Listifadedeki tüm s işleviyle değiştirin ({##,+##}&).


10

Python 2, 95 bayt

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

Bu, her bir boyut üzerinde yineleyerek, toplamlarını NumPy kullanarak birleştirir.

Ben r_golf için oldukça harika NumPy , tökezledi . r_[:n]daha kısa range(n)ve çok daha güçlüdür (ör. r_[:4, 7, 8, 10:100:10]). Ayrıca, keyfi bir eksen boyunca birleştirme gibi başka şeyler de yapabilir.

Örnek kullanım:

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

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

3 bayt golf oynamak ve uygun giriş formatını bulmak için @ user23013.

TryAPL ile test senaryolarını çevrimiçi doğrulayın .

Fikir

Genel fikir, APL'nin çok daha kısa bir uygulamaya izin verdiği CJam başvurumla aynıdır. Sadece iki adımdan oluşur:

  1. Diziyi en dış boyutunda toplayın.

  2. Her alt dizi için 1. adımı tekrarlayın.

kod

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

Sadece orijinal kodunuzun giriş formatını anladınız: ,⊂(,1)(,1)(,1)(,0)ve ,⊂,⊂,⊂,¯1sırasıyla. Böylece başka bir karakteri kaldırabilirsiniz.
jimmy23013

2
@ user23013: Kodum işe yaradı! Giriş biçiminin gerçek koddan daha doğru bir şekilde elde edilmesinin zor olduğu bir programlama dilini sevmelisiniz ...
Dennis

6

Pip , 18 15 bayt

{a-a?fMaAE$+aa}

Bu, diziyi bağımsız değişken olarak alan ve sonucu döndüren anonim bir işlevdir. -pOkunabilir çıktı elde etmek için bayrağı kullanarak örnek çağırma :

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

Fikir, bağımsız olarak türetilmiş olsa da , temelde Dennis'in APL'si ile aynıdır . Daha spesifik olarak:

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

Bu yöntem, +(diğer birçok işleçle birlikte), APL gibi dizi programlama dillerinden esinlenen bir özellik olan Pip'deki listelerde öğe olarak işlev görmesi nedeniyle çalışır . Yani $+gibi bir liste [[1 2 3] [4 5 6]], sonuç [5 7 9]istediğiniz gibi. Liste veya skaler testinde de kullanılır: doğrudur ( [1 2 3] - [1 2 3]verir [0 0 0]boş liste hariç tüm listeler gibi).

Önceki 18 baytlık sürüm:

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

değişiklikler:

  1. Skaler veya liste testinde bir bayt kaydedildi - önceki yöntem, argümana katılmak (boş dizede) ve birleştirilmemiş kendi kendine eşit olup olmadığını test etmekti (çünkü [1 2 3] != 123 );
  2. Parantez ortadan kaldırıldı. Orijinalde gereklidirler, çünkü Mdaha düşük önceliğe sahiptir ?(muhtemelen bunu şimdi değiştireceğim, ancak şimdi): onlarsız, kod olarak ayrıştırılır (Ja=a?af)M(aAE$+a), tuhaf hata mesajlarına yol açar. Bununla birlikte, üçlü bir operatörün orta argümanı, herhangi bir önceliğin herhangi bir ifadesi olabilir , parantez gerekmez. Bu yüzden, listeyi gerçeğe uygun hale getirerek, bu iki baytı kurtarabilirim.

2
Bu, ilginç bir dil. Öte yandan, operatörler CJam ve Pyth'de eksik olanlardır.
Dennis

@Dennis Teşekkürler! Hala devam eden bir çalışma, ancak oldukça iyi yaptığı bazı görevler var.
DLosc

5

APL (25)

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

APL dizileri yerleşik boyutlara sahiptir, bu nedenle bu n boyutlu bir dizi alan ve daha sonra her boyut boyunca toplanan bir işlevdir .

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

Açıklama:

  • N←⍵: diziyi saklayın N.
  • ⍴⍴N: Nsahip olduğu boyutların miktarını elde edin . ( boyutları verir, yani ⍴↑(1 2 3)(4 5 6)verir 2 3, böylece ⍴⍴boyutların boyutlarını verir.)
  • {... }¨⍳: 1'den 1'e kadar olan her sayı için⍴⍴N :
    • +/[⍵]N: Nboyut boyunca toplam
    • N,[⍵]←: sonuca Nbu boyutta katıl
  • N: sonunda, geri dön N.

Dizi singletons içeriyorsa, bu işi yapmak gibi olamaz. Üçüncü veya dördüncü test senaryosu için bu işlevi nasıl adlandırırsınız?
Dennis

3
@Dennis: Fonksiyona çok boyutlu bir dizi iletmeniz gerekir. Ne ↑(1 2 3)(4 5 6)yapıyor basitçe kullanarak 2 1 boyutlu olanlardan 2 boyutlu dizi inşa edilir . Yerleşik bir gösterim değildir ve düşünme biçiminizi genelleştirmez. 3. ve 4. dizileri oluşturmanın kanonik yolu olacaktır 1 4 1⍴1 1 1 0ve 1 1 1 1⍴¯1ancak boyutlara değinmeden bunları inşa etmek de mümkündür, örneğin üçüncü dizi de inşa edilebilir ↑⍉⍪(,1)(,1)(,1)(,0), dördüncü dizisi de inşa edilebilir ↑⍪⊂⍪¯1.
marinus

Tamam, bu her şeyi açıklıyor. Özyinelemeli bir yaklaşımın uygulanması, diziler olduğunu düşündüğüm şey için iyi çalışıyor (örn. f←{0=≡⍵:⍵⋄f¨⍵,+/⍵}⋄f((1 2)(3 4))((5 6)(7 8))), Ancak iç içe vektörler ve diziler farklı ve eskilerin skalerleri tektonlardan ayırmadığı görülüyor ...
Dennis

2
@Dennis golfed: {×≡⍵:∇¨⍵,+/⍵⋄⍵}((1 2)(3 4))((5 6)(7 8)). Sabit: {×⍴⍴⍵:∇↓⍵,+/⍵⋄⍵}1 4 1⍴1 1 1 0. Şimdi Mathematica'dan daha kısa ...
jimmy23013

3

CJam, 36 bayt

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

Bu, bir diziyi yığından alan ve karşılığında bir dizi bırakan özyinelemeli adlı bir işlevdir.

CJam yorumlayıcısındaki test senaryolarını deneyin .

Fikir

Ne yazık ki, CJam'in keyfi olarak iç içe diziler eklemesine izin veren bazı otomajik operatörleri yoktur, bu yüzden bunu kendimiz uygulamak zorundayız. Neyse ki, bu görev için yararlı olduğunu kanıtlayan iki infix operatörü :(azaltma) ve .(vektörleştirme) yapar.

Birinci adım, boyutların sayısını hesaplamaktır. Bu kolaydır: Diziyi dize temsiline dönüştürün ve baştaki [ 'lerin sayısını sayın .

Şimdi, bir boyuttaki bir diziyi azaltmak için genellikle sadece yürütürsünüz :+:

[1 2] :+ e# Pushes 3.

İki boyutlu bir dizi için +toplama yerine birleştirme gerçekleştirir, bu yüzden onu vektörelleştirmeliyiz:

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

Şimdi, üç boyutlu bir dizi için .+, iki boyutlu diziler üzerinde çalışacak ve bir kez daha birleştirme gerçekleştirecekti. Bu kez, vektörelleştirmeliyiz .+:

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

Genel durum için, bir boyut D dizisi, bir :, D - 1 . ve bir zincirlemeliyiz +.

Tabii ki, bu sadece diziyi sadece en dış boyutunda toplar. Bunu , boyutu hesaplayan (ve sıfırsa hiçbir şey yapmayan), yukarıda belirtilen toplamı gerçekleştiren ve son olarak kendini dizinin elemanlarına uygulayan bir S işlevini tanımlayarak çözebiliriz .

kod

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

Yakut ( 181 139 119 108 bayt)

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

Girdinin JSON olarak geçtiğini varsayar.


Ve aslında, ayrıştırılmış bir diziyi kabul eden ve bir dizi döndüren bir işlev yazabilir ve dbu cevapta yalnızca 95 bayt sayabilirsiniz .
jimmy23013

2

Java, 669 bayt

yalan söylemeyeceğim, bunun için kendimle gurur duyuyorum: 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;}}

test ile genişletildi:

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

}

genişletilmiş test sürümünü çalıştırmak aşağıdakileri yazdırır:

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

genişletilmiş sürüm için erm, satır: Array.set (sonuç, x, toplam (Array.get (diziA, x), Array.get (diziB, x ++))); _sum (...) yönteminde sum (...) değil, _sum (...) çağrılmış olmalıdır. benim kötü
Jack Ammo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.