Вдохновленный этим .
Агата Стивендейл, второкурсница, которая действительно увлекается растровой графикой, прошла курс линейной алгебры. Теперь она представляет матрицы в виде прямоугольников, но в своем художественном сознании она прикрепляет диагональные линии к этим прямоугольникам и пытается вычислить следы вдоль них. На самом деле она хочет вычислить следы всех матриц, а не только квадратов.
Поскольку Агата - художник, она знает, как рисовать линии в своем любимом графическом редакторе, и последний использует алгоритм Брезенхэма для построения линий. Она даже проверила Википедию и нашла псевдокод:
function line(x0, y0, x1, y1)
real deltax := x1 - x0
real deltay := y1 - y0
real deltaerr := abs(deltay / deltax) // Assume deltax != 0 (line is not vertical),
// note that this division needs to be done in a way that preserves the fractional part
real error := 0.0 // No error at start
int y := y0
for x from x0 to x1
plot(x,y)
error := error + deltaerr
while error ≥ 0.5 then
y := y + sign(deltay) * 1
error := error - 1.0
(Обратите внимание, что этот псевдокод работает только для уклонов меньше 1; для высоких сеток аналогичная обработка должна быть выполнена, но с повторением цикла y
. См. Этот раздел для двух случаев.)
Агата представляет матрицу в виде прямоугольника, рисует в ней диагональную линию, а алгоритм Брезенхэма определяет, какие элементы матрицы принадлежат диагонали. Затем она берет их сумму, и это то, что она хочет реализовать в как можно меньшем количестве байтов, потому что она плохая ученица и не может позволить себе жесткие диски большой емкости для хранения своего кода.
задача
Учитывая матрицу A , верните сумму элементов, которые лежат на растеризованной главной диагонали (сверху вниз, слева направо), где последняя определяется алгоритмом линии Брезенхэма. То есть, предполагая, что матрица представляет сетку m × n , нарисуйте линию на этой сетке от A [1, 1] до A [m, n], используя алгоритм Брезенхэма, и возьмите сумму всех элементов на линии. Обратите внимание, что для матриц 1 × N и N × 1 вся матрица становится собственной диагональю (потому что именно так можно нарисовать линию от первого элемента первой строки до последнего элемента последней строки).
Входные данные: реальная матрица (может быть матрица 1 × 1, матрица строк, матрица столбцов или прямоугольная матрица). Выход: число.
Обратите внимание, что некоторые источники (например, псевдокод Википедии выше) используют проверку условия error≥0.5
, в то время как другие источники используют error>0.5
. Вы должны использовать изначально опубликованную функцию one ( error≥0.5
), но если альтернатива error>0.5
в вашем коде короче, вам разрешено ее реализовать (так как это кодовый гольф), но упомяните об этом явно . Смотри контрольный пример 4.
Правила вызова
- Форматы ввода / вывода являются гибкими. Матрица может представлять собой несколько строк разделенных пробелами чисел, разделенных символами новой строки, или массив векторов строк, или массив векторов столбцов и т. Д.
- Это код-гольф , поэтому выигрывает самый короткий ответ в байтах.
- К вашему ответу применяются стандартные правила , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы.
- Лазейки по умолчанию запрещены.
Контрольные примеры
[[1,2,3],[4,5,6],[7,8,9]]
→1+5+9
→ Выход:15
.
[[1,2,3,4],[5,6,7,8]]
→1+2+7+8
→ Выход:18
.
[[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18],[19,20,21,22,23,24]]
→1+8+9+16+17+24
→ Выход:75
.
[[1,2,3,4,5],[6,7,8,9,10]]
→1+2+8+9+10
(используя≥
условие ошибки) → выход:30
.
Однако, если будет короче использовать строгое неравенство >
в вашем коде, то разрешенный вывод будет 1+2+3+9+10=25
, но вы должны упомянуть об этом отдельно.
[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
→1+5+8+12
→ Выход:26
.
[[-0.3,0.5]]
→ выход:0.2
.[[3.1],[2.9]]
→ выход:6
.[[-5]]
→ выход:-5
.
Больше информации об алгоритме Брезенхэма
- http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm - набор алгоритмов для разных языков;
- https://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html - хорошее объяснение с различными случаями для склонов;
- https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm ;
[[1,2,3,4,5],[6,7,8,9,10]]
.[[1,2],[3,4],[5,6],[7,8],[9,10]]
28
(с≥
, ожидаемой реализацией) или 27 (с>
, необязательной реализацией.)Ответы:
Желе , 25 байт
Попробуйте онлайн!
источник
SmileBASIC,
10199 байтПервоначально я думал об использовании функции GLINE для рисования линии, но, похоже, она не использует правильный алгоритм. Тем не менее, GTRI , кажется, работает,
Тестовый пример 4 выводит 30.
Ввод - это двумерный массив в форме [Y, X] вместе с шириной / высотой (проверить размеры массива невозможно, только общее количество элементов).
источник
JavaScript (ES6),
110103 байтВыходы
25
для 4-го контрольного примера.Попробуйте онлайн!
Или 88 байт, если разрешено брать размеры матрицы в качестве входных данных.
источник
Python 3.X, 269 байт
С вводом в виде строк с разделителями-запятыми чисел с разделителями-пробелами.
import math;c=math.ceil;a=[[float(k)for k in q.split(" ")]for q in input().split(",")];_=len;m=lambda f,t,x,y,e,d:sum(x[0]for x in a)if 2>_(a[0])else m(*[0]*4,*[(_(a)-1)/(_(a[0])-1)]*2)if f else m(f,t+a[y][x],x+1,y+c(e-0.5),e+d-c(e-0.5),d)if x<_(a[0])else t;m(1,*[0]*5)
Pre-гольф:
источник
c=math.ceil
сделать программу длиннее ...[]
междуsum(..)
.a if c else b
часто может бытьc and a or b
.input("")
может бытьinput()
.FMSLogo , 136 байтов
Полная программа, запрашивает ввод у пользователя (всплывающее диалоговое окно) и затем выводит вывод на экран.
Просто нарисуйте линию на экране и рассчитайте результат. Используйте строгое неравенство.
Это поддерживает только размер матрицы до размера холста FMSLogo (около 500 × 500)
Код Ungolfed:
источник