Сумма диагоналей

19

Возьмите матрицу положительных целых чисел в качестве входных данных и выведите отдельные суммы элементов по диагональным линиям через матрицу.

Вы должны считать только линии, идущие по диагонали вниз и вправо. Вы должны начать с диагонали, которая содержит только нижний левый элемент, затем диагональ на две длины выше этой (если она существует) и так далее до диагонали, которая содержит только верхний правый элемент, как показано ниже.

Пример:

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

Haskell , 40 37 байт

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

Попробуйте онлайн! Использование: (foldl1$(.(++z)).zipWith(+).(0:)) [[1,2,3],[4,5,6]].

Редактировать: Спасибо Орджану Йохансену за -3 байта!

Ungolfed:

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

zсписок бесконечно многих нулей В fмы сгиб список списков mпутем объединения двух списков с помощью функции #. В #первом списке sсодержатся накопленные суммы столбцов, а во втором списке t- новая строка, которая должна быть добавлена. Мы сдвигаем sодин элемент вправо, добавляя ноль к переднему и поэлементному добавлению sи tс zipWith(+). Так какs могут быть сколь угодно большими, мы должны дополнить их tдостаточным количеством нулей z.

Laikoni
источник
Короче бессмысленно foldl1$(.(++z)).zipWith(+).(0:).
Эрджан Йохансен,
6

Mathematica, 53 54 байта

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

Чистая функция, принимающая 2D-массив в качестве входных данных и возвращающая список. (Записи не должны быть целыми или четными числами.) Diagonal[#,k]Возвращает kдиагональ th выше (или ниже, если kона отрицательна) главной диагонали. {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(:)), а не придерживаться соглашения MATLAB, как это делает MATL?
Стьюи Гриффин
@ StewieGriffin Я иногда думал об этом. Мое сомнение было больше между sum(x)и sum(x,1). Для матрицы xфакт, который sum(x)ведет себя по-разному, если матрица имеет 1 строку, иногда раздражает. Но в конце концов я решил пойти с Matlab, чтобы два языка стали ближе; и добавить некоторые 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 для уменьшения имеет на один элемент меньше; он увеличивается еще на один элемент в каждой строке.
Орджан Йохансен
Это просто умно ... нет ŒD?
Эрик Outgolfer
@EriktheOutgolfer Еще раз, ŒDстранный порядок не позволил ему быть полезным.
Деннис
@Dennis Тогда я думаю, что я сделал бы что-то, что не было бы так странно упорядочено ... о, может быть, 3 монады могут поступить.
Эрик Outgolfer
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

CJam , 22 21 байт

Сохранено 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)
Emigna
источник
2

J 7 байт

+//.@|.

Попробуйте онлайн!

Это довольно просто:

+//.@|.
+/        sum
  /.      on oblique lines
    @|.   on the reversed array

Косые перевернутые линии являются диагоналями массива, так что это просто суммирование диагоналей.

Конор О'Брайен
источник
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

Perl 5, 47 байт

map{$j=--$.;map{@a[$j++]+=$_}split}<>
print"@a"
faubi
источник
1

R, 45 байт

Безымянная функция, принимающая объект класса матрицы в качестве входных данных:

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

Используя идею, объясненную в этом ответе.

Billywob
источник
Я полагаю, что правила в этом соревновании позволяют вам избавиться от призыва 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.

Выход:

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,:)),endэкономит 6 байт. Octave может выполнять прямую индексацию и встроенные назначения. К сожалению, допускать, что переменная существует в рабочем пространстве до запуска кода, не разрешено, поэтому я думаю, что вы должны использовать input, как это, возвращая ее до 75 байт. Хороший подход, так что +1 от меня :) И добро пожаловать в PPCG! =)
Стьюи Гриффин
Также zeros(m-1,m)можно записать ~e(m-1,m), сохранив 4 байта :) Аккуратно, а?
Стьюи Гриффин
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чтобы быть короче, потому что часть, чтобы получить отрицательные значения не работали).

HyperNeutrino
источник
Я получаю ошибку для последнего контрольного примера. tio.run/nexus/…
Деннис
0

Awk, 67 байт

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

Ungolfed:

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

Awk разделяется на пробел $n- это nполе (с 1 индексом); NFэто количество полей в строке, NRэто номер текущей строки. Неопределенные переменные равны 0 и создаются при первом использовании.

Kevin
источник
0

PHP, 86 байт

дружественное к памяти решение в двух вариантах:

<?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) или попробуйте их онлайн

Titus
источник
0

Clojure, 81 байт

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

Довольно многословно, поскольку в нем списки с нулями, так что мы можем просто вычислить сумму по столбцам.

NikoNyrh
источник
0

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

J42161217
источник