Ma trận theo dõi cho bất kỳ ma trận nào thông qua rasterisation dòng của Br Brnhamnham


12

Lấy cảm hứng từ điều này .

Agatha Stephendale, một sinh viên năm hai thực sự say mê đồ họa raster, đã tham gia một khóa học về đại số tuyến tính. Bây giờ cô ấy tưởng tượng ma trận là hình chữ nhật, nhưng trong tâm trí nghệ thuật của mình, cô ấy gắn các đường chéo vào những hình chữ nhật đó và cố gắng tính toán dấu vết dọc theo chúng. Trong thực tế, cô ấy muốn tính toán dấu vết của tất cả các ma trận, không chỉ là hình vuông.

Vì Agatha là một nghệ sĩ, cô ấy biết cách vẽ các đường trong trình chỉnh sửa hình ảnh yêu thích của mình và sau này sử dụng thuật toán của Bresenham để vẽ các đường kẻ. Cô thậm chí đã kiểm tra Wikipedia và tìm thấy mã giả:

nhập mô tả hình ảnh ở đây

 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

(Lưu ý rằng mã giả này chỉ hoạt động đối với độ dốc nhỏ hơn 1; đối với lưới điện cao, nên thực hiện một cách xử lý tương tự, nhưng với một vòng lặp y. Xem phần này cho hai trường hợp.)

Agatha tưởng tượng một ma trận như một hình chữ nhật, vẽ một đường chéo trong đó và thuật toán của Bresenham xác định các phần tử nào của ma trận thuộc về đường chéo. Sau đó, cô ấy lấy số tiền của họ, và đây là những gì cô ấy muốn thực hiện trong càng ít byte càng tốt bởi vì cô ấy là một sinh viên nghèo và không đủ khả năng để có ổ cứng dung lượng lớn để lưu trữ mã của mình.

Bài tập

Đưa ra một ma trận A , trả về tổng của các phần tử nằm trên đường chéo chính rasterised (từ trên cùng bên trái xuống dưới bên phải), trong đó phần tử sau được xác định bởi thuật toán dòng của Bresenham. Nghĩa là, giả sử rằng ma trận đại diện cho lưới m × n , vẽ một đường thẳng trên lưới đó từ A [1, 1] đến A [m, n] bằng thuật toán của Bresenham và lấy tổng của tất cả các phần tử trên dòng. Lưu ý rằng đối với ma trận 1 × NN × 1 , toàn bộ ma trận trở thành đường chéo của chính nó (vì đây là cách người ta vẽ một đường thẳng từ phần tử đầu tiên của hàng đầu tiên đến phần tử cuối cùng của hàng cuối cùng).

Đầu vào: ma trận thực (có thể là ma trận 1 × 1 , ma trận hàng, ma trận cột hoặc ma trận hình chữ nhật). Đầu ra: một số.

Lưu ý rằng một số nguồn (ví dụ: mã giả của Wikipedia ở trên) sử dụng kiểm tra điều kiện error≥0.5, trong khi các nguồn khác sử dụng error>0.5. Bạn nên sử dụng một ( error≥0.5) được đăng ban đầu , nhưng nếu mã thay thế error>0.5ngắn hơn trong mã của bạn, thì bạn được phép thực hiện nó (vì đây là mã golf), nhưng đề cập rõ ràng . Xem trường hợp kiểm tra 4.

Quy tắc thử thách

  • Các định dạng I / O rất linh hoạt. Một ma trận có thể là một vài dòng số được phân tách bằng dấu cách được phân tách bằng dòng mới hoặc một mảng các vectơ hàng hoặc một mảng các vectơ cột, v.v.
  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte thắng.
  • Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số thích hợp và kiểu trả về, các chương trình đầy đủ.
  • Lỗ hổng mặc định bị cấm.

Các trường hợp thử nghiệm

  1. [[1,2,3],[4,5,6],[7,8,9]]1+5+9→ đầu ra : 15.

Trường hợp kiểm tra 1

  1. [[1,2,3,4],[5,6,7,8]]1+2+7+8→ đầu ra : 18.

Trường hợp thử nghiệm 2

  1. [[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→ đầu ra : 75.

Trường hợp thử nghiệm 3

  1. [[1,2,3,4,5],[6,7,8,9,10]]1+2+8+9+10(sử dụng điều kiện lỗi) → đầu ra : 30.

Trường hợp thử nghiệm 4

Tuy nhiên, nếu việc sử dụng bất đẳng thức nghiêm ngặt >trong mã của bạn sẽ ngắn hơn , thì đầu ra được phép là 1+2+3+9+10=25, nhưng bạn nên đề cập riêng.

Trường hợp thử nghiệm 5

  1. [[1,2,3],[4,5,6],[7,8,9],[10,11,12]]1+5+8+12→ đầu ra : 26.

Trường hợp thử nghiệm 5

  1. [[-0.3,0.5]]→ đầu ra : 0.2.

  2. [[3.1],[2.9]]→ đầu ra : 6.

  3. [[-5]]→ đầu ra : -5.

Thông tin thêm về thuật toán của Bresenham


Trường hợp kiểm tra yêu cầu : [[1,2,3,4,5],[6,7,8,9,10]].
dùng202729

@ user202729 Đã thêm nó để giải quyết sự mơ hồ.
Andreï Kostyrka

Chúng ta có thể có được một trường hợp thử nghiệm cao hơn nó rộng không? Thích[[1,2],[3,4],[5,6],[7,8],[9,10]]
Giuseppe

@Giuseppe Bắt. Xem trường hợp 5 ngay bây giờ. Ví dụ của bạn, câu trả lời nên là 28(với , việc triển khai dự kiến) hoặc 27 (với >, việc thực hiện tùy chọn.)
Andreï Kostyrka

Chương trình chỉ có thể hỗ trợ ma trận lên đến một kích thước cố định (giả sử, 500 × 500)?
dùng202729

Câu trả lời:



3

SmileBASIC, 101 99 byte

DEF D A,W,H
GCLS
GTRI.,0,0,0,W-1,H-1FOR I=0TO W*H-1=I MOD W
S=S+A[I/W,M]*!!GSPOIT(M,I/W)NEXT?S
END

Ban đầu tôi nghĩ sử dụng hàm GLINE để vẽ một đường thẳng, nhưng dường như không sử dụng đúng thuật toán. Tuy nhiên, GTRI không dường như làm việc,

Trường hợp thử nghiệm 4 đầu ra 30.

Đầu vào là một mảng 2D ở dạng [Y, X], cùng với chiều rộng / chiều cao (không có cách nào để kiểm tra kích thước của một mảng, chỉ có tổng số phần tử).


1

JavaScript (ES6), 110 103 byte

Đầu ra 25cho trường hợp thử nghiệm thứ 4.

a=>(X=a[x=y=0].length-1,Y=1-a.length,g=e=>a[y][x]+(x-X|y+Y&&g(e+(e*2>Y&&++x&&Y)+(e*2<X&&++y&&X))))(X+Y)

Hãy thử trực tuyến!

Hoặc 88 byte nếu lấy kích thước của ma trận làm đầu vào được cho phép.


1

Python 3.X, 269 byte

Với đầu vào là các hàng được phân cách bằng dấu phẩy của các số được phân tách bằng dấu cách.

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)

Chơi golf trước:

def line(a):
   if len(a[0])<2: return sum([x[0] for x in a])
   e = d = abs((len(a)-1)/(len(a[0])-1))
   y=t=0
   for x in range(len(a[0])): 
       t += a[y][x]
       f = ceil(e-0.5)
       y += f
       e += d-f
   return t

Có vẻ như điều đó c=math.ceillàm cho chương trình dài hơn ...
user202729

Ngoài ra, bạn không cần []giữa sum(..). a if c else bthường có thể c and a or b.
dùng202729

input("")có thể input().
dùng202729

Ngoài ra ... định dạng đầu vào / đầu ra là gì? In ra màn hình?
dùng202729

1

FMSLogo , 136 byte

make 1 rl
setxy -1+count :1 -1+count last :1
pu home
make 9 0
foreach :1[foreach ?[if
0=last pixel[make 9 :9+?]fd 1]setxy xcor+1 0]pr :9

Chương trình đầy đủ, nhắc người dùng nhập liệu (hộp thoại bật lên) và sau đó in đầu ra ra màn hình.

Chỉ cần vẽ một đường trên màn hình và tính toán đầu ra. Sử dụng bất bình đẳng nghiêm ngặt.


Điều này chỉ hỗ trợ kích thước ma trận lên đến kích thước vải của FMSLogo (khoảng 500 × 500)

Mã bị đánh cắp:

Make "input ReadList
SetXY (-1+Count :input) (-1+Count Last :input)
PenUp
Home
Make "sum 0
ForEach :input[
    ForEach ?[
        If 0=Last Pixel[
            Make "sum :sum+?
        ]
        Forward 1
    ]
    SetXY XCor+1 0
]
Print :sum
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.