Підсумуйте діагоналі


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

Редагувати: Спасибі Ørjan Johansen за -3 байти!

Безголівки:

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:).
Ørjan Johansen

6

Математика, 53 54 байти

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

Чиста функція, що приймає 2D-масив як вхідний і повертає список. (Записи не повинні бути цілими чи парними числами.) Diagonal[#,k]Повертає таку kдіагональ вище (або нижче, якщо 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, як це здається?
Стюі Гріффін

@StewieGriffin Я інколи про це думав. Мої сумніви були більше між sum(x)і sum(x,1). Для матриці xфакт, який sum(x)поводиться по-різному, якщо матриця має 1 рядок, іноді дратує. Але врешті-решт я вирішив поїхати з Матлабом, тож дві мови ближче; і додайте деякі 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 для зменшення має один менший елемент; вона збільшується на ще один елемент у кожному рядку.
Ørjan Johansen

Це просто розумно ... ні ŒD?
Erik the Outgolfer

@EriktheOutgolfer Знову ŒDдивне впорядкування завадило йому бути корисним.
Денніс

@ Денніс Тоді я думаю, що я зробив би щось, що не має такого дивного впорядкування ... о, може бути, 3 монади можуть бути вхідними.
Erik the 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 Я згоден, переїзд був поганим кроком. Але брати довжину теж занадто довго!
Ніл

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

Пітон, 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]}

Безголівки:

{
    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

математика 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.