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


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.


Короче бессмысленно 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)



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

R, 45 байт

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

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

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


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


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


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


0

Clojure, 81 байт

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

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


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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.