Сума у ​​кожному вимірі


20

Вам дається багатовимірний масив цілих чисел. Кожен вимір має фіксований розмір (так що він буде завжди прямокутним, якщо він буде 2D). Ваша програма повинна розраховувати суми у кожному вимірі та додавати їх як нові останні елементи у цьому вимірі.

Припустимо , що вхідні і вихідні масиви А і В, а розмір розмірності I з А н я . B матиме таку ж кількість розмірів, що і A, і розмір розміру, який я був би 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

Математика, 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]]. Потім замініть всі Lists у виразі функцією ({##,+##}&).


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 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 дозволяє значно скоротити реалізацію. Він складається лише з двох етапів:

  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] дає [0 0 0], що є правдою (як і всі списки, крім порожнього списку).

Попередня версія 18-байт:

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

Зміни:

  1. Збережено байт на тесті скалярного або списку - попередній метод полягав у тому, щоб приєднатись до аргументу (у порожній рядку) і перевірити, чи дорівнює його неприєднаному самості (працює тому, що [1 2 3] != 123 );
  2. Видалено дужки. Вони потрібні в оригіналі, оскільки Mце нижчий пріоритет, ніж ?(хоча я, мабуть, збираюся це змінити, особливо зараз): без них код би розбирався як (Ja=a?af)M(aAE$+a), що призводить до химерних повідомлень про помилки. Однак середнім аргументом потрійного оператора може бути будь-який вираз будь-якого пріоритету, не потрібні дужки. Отже, роблячи список справжнім випадком, я можу зберегти ці два байти.

2
Це цікава мова, яку ви там отримали. Оператори в деталях - це те, чого не вистачає в CJam та Pyth.
Денніс

@Dennis Дякую! Це ще велика робота в процесі роботи, але є деякі завдання, з якими вона непогано працює.
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 :
    • +/[⍵]N: сума Nпо виміру
    • N,[⍵]←: приєднайте результат до Nцього виміру
  • N: нарешті, повернення N.

Я не можу зробити цю роботу, якщо масив містить одинакові. Як би ви назвали цю функцію для третього чи четвертого тестового випадку?
Денніс

3
@Dennis: вам потрібно передати функцію багатовимірному масиву. Що ↑(1 2 3)(4 5 6)робиться, це просто побудувати двовимірний масив з 2 одновимірних, використовуючи . Це не вбудована нотація і не узагальнює те, як ви могли подумати. Канонічним способом побудови 3-го та 4-го масивів було б 1 4 1⍴1 1 1 0і 1 1 1 1⍴¯1, але також можна їх побудувати, не посилаючись на розміри, наприклад, третій масив також може бути побудований з ↑⍉⍪(,1)(,1)(,1)(,0), четвертий може бути побудований за допомогою ↑⍪⊂⍪¯1.
Марина

Гаразд, це все пояснює. Моя наївна реалізація рекурсивного підходу добре працює, як я вважав, це масиви (наприклад 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

Це рекурсивна названа функція, яка спливає масив зі стека і залишає один натомість.

Спробуйте приклади тестування в інтерпретаторі CJam .

Ідея

На жаль, у CJam немає автоматизованого оператора, який дозволяє додавати довільно вкладені масиви, тому нам доведеться реалізовувати його самостійно. На щастя, це робить, що два оператори інфікування :(зменшення) та .(векторизація) виявляться корисними для цього завдання.

Перший крок - обчислення кількості розмірів. Це легко: Перетворіть масив у його рядкове подання та підрахуйте кількість ведучих [ 's.

Тепер, щоб зменшити масив одного виміру, ви зазвичай просто виконуєте :+:

[1 2] :+ e# Pushes 3.

Для масиву з двох вимірів +виконується конкатенація замість додавання, тому ми мусимо його векторизувати:

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

Тепер, для масиву з трьох вимірів, .+він оперуватиме масивами двох вимірів і виконує, знову ж таки, конкатенацію. Цього разу ми мусимо векторизувати .+:

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

Для загального випадку, масив розмірності D , ми маємо ланцюжок один :, D - 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

Ruby ( 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.


Насправді ви можете просто написати функцію, яка приймає проаналізований масив і повертає масив, і лише підраховувати 95 байтів для dцієї відповіді.
jimmy23013

2

Java, 669 байт

не брешу, я дуже пишаюся собою за це: с

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 (результат, х, сума (Array.get (arrayA, x), Array.get (arrayB, x ++))); у методі _sum (...) слід було б називати _sum (...), а не суму (...). мій поганий
Джек Аммо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.