Diện tích của đa giác này là gì?


19

Tính diện tích của một đa giác.

Lấy cảm hứng từ video thuật toán dây giày này.

Bài tập

Công việc của bạn là tạo ra một chương trình hoặc hàm tính diện tích của một đa giác. Chương trình hoặc chức năng được xác định theo định nghĩa mặc định trong meta.

Đầu vào

Bạn sẽ nhận được tọa độ X và Y của mỗi đỉnh của đa giác. Bạn có thể lấy đầu vào làm danh sách các bộ dữ liệu ( [[x1, y1], [x2, y2], etc]), ma trận hoặc danh sách phẳng ( [x1, y1, x2, y2, etc]). Hai danh sách chứa xytọa độ tương ứng cũng được cho phép. Các đỉnh được đánh số ngược chiều kim đồng hồ và đỉnh đầu tiên giống như đỉnh cuối cùng được cung cấp, do đó đóng đa giác.

Nếu bạn muốn, bạn có thể lấy đầu vào mà không có đỉnh cuối cùng (vì vậy hãy nhận mỗi tọa độ chỉ một lần).

Bạn có thể giả sử rằng các cạnh của đa giác không giao nhau. Bạn cũng có thể giả sử rằng tất cả các đỉnh có tọa độ nguyên.

Đầu ra

Diện tích của đa giác. Tất cả các phương pháp đầu ra tiêu chuẩn được cho phép. Nếu ngôn ngữ của bạn không cho phép phân chia float và giải pháp sẽ không phải là số nguyên, bạn được phép trả về một phân số. Phân số không nhất thiết phải được đơn giản hóa, vì vậy việc trả lại 2/4sẽ được cho phép.

Giành chiến thắng

Mã ngắn nhất sẽ thắng!

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

[[4,4],[0,1],[-2,5],[-6,0],[-1,-4],[5,-2],[4,4]]
55

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

[[1,1],[0,1],[1,0],[1,1]]
0.5
1/2

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


Là đầu vào như [x1, x2, x3], [y1, y2, y3]được phép?
lập trình

@ lập trình5000 và Martin Ender, vâng, tôi sẽ chỉnh sửa nó trong :)
JAD

Tôi đồng ý, bỏ phiếu để mở lại.
lập trình

1
@flawr Tôi đã làm điều đó một bản sao của điều này. Nó không thực sự là một bản sao của mục tiêu dupe của nó, để áp dụng phương pháp tương tự như ở đây một cách đệ quy sẽ yêu cầu tìm các đỉnh đang giao nhau và sẽ yêu cầu sắp xếp các tập hợp con theo kiểu ngược chiều kim đồng hồ - điều đó có vẻ phức tạp hơn nhiều.
Jonathan Allan

Câu trả lời:


13

Thạch ,  8  6 byte

-1 byte nhờ Emigna (dự phòng , ÆḊcó độ sâu bên trái là 2)
-1 byte nhờ Emigna, một lần nữa (một nửa H, là dấu phẩy động không cần ÷2)

ṡ2ÆḊSH

Một liên kết đơn âm lấy một danh sách các cặp tọa độ theo chiều ngược chiều kim đồng hồ theo các ví dụ (với một lần lặp lại) và trả về khu vực.

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

Làm sao?

Áp dụng thuật toán dây giày, giống như được mô tả trong video (mà tôi tình cờ cũng chỉ xem vào một ngày khác!)

ṡ2ÆḊSH - Link: list of [x,y] coordinate pairs anticlockwise & wrapped, p
ṡ2     - all overlapping slices of length 2
  ÆḊ   - determinant (vectorises)
    S  - sum
     H - halve

Trường hợp thử nghiệm thứ hai trả về `-0,5` cho tôi: o
JAD

Ồ, tôi sẽ phải xem thử ...
Jonathan Allan

Đó là bởi vì như [x,y]tọa độ, chúng được cho theo chiều kim đồng hồ chứ không phải ngược chiều kim đồng hồ. Một đầu vào [[1,1],[0,1],[1,0],[1,1]]sẽ trả về a 0.5.
Jonathan Allan

1
Rất tiếc, tôi sẽ chỉnh sửa rằng: D
JAD

1
Ngoài ra, Hthay vì÷2
Emigna



16

JavaScript (ES6), 69 67 47 byte

Cảm ơn @Rick đã nhận thấy rằng chúng tôi không cần giá trị tuyệt đối nếu các đỉnh được đảm bảo được sắp xếp theo thứ tự ngược chiều kim đồng hồ và đề nghị lấy danh sách phẳng làm đầu vào, tiết kiệm 20 byte!

Đưa đầu vào dưới dạng một danh sách các đỉnh, bao gồm cả đỉnh cuối cùng.

f=([x,y,...a])=>1/a[0]?x*a[1]/2-y*a[0]/2+f(a):0

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

Làm sao?

n

mộtremột= =|(x0y1-y0x1)+(x1y2-y1x2)+Giáo dục+(xn-1y0-yn-1x0)2|


Rất ấn tượng! Bạn có thể giải thích làm thế nào nó hoạt động?
Rugnir

Các đỉnh trong trường hợp thử nghiệm thứ hai đã bị đặt nhầm. Cơ bụng không cần thiết.
Rick

Bạn cũng có thể lưu 7 byte chuyển sang một danh sách phẳng:a=>(g=([x,y,...a])=>1-a?0:x*a[1]-y*a[0]+g(a))(a)/2
Rick

@Rick là đúng - abs không cần thiết. Không có nó, công thức tính diện tích đã ký, là số dương vì các đỉnh được cho theo thứ tự ngược chiều kim đồng hồ.
Angs

@Rick Cảm ơn! Cập nhật ... khoảng 10 tháng sau: /
Arnauld

7

R, 54 52 byte

pryr::f({for(i in 2:nrow(x))F=F+det(x[i-1:0,]);F/2})

Mà đánh giá chức năng:

function (x) 
{
    for (i in 2:nrow(x)) F = F + det(x[i - 1:0, ])
    F/2
}

Làm cho việc sử dụng được xác định trước F = FALSE = 0. Triển khai thuật toán dây giày trong video được liên kết :)

-2 byte nhờ Giuseppe


-1 byte cho i+-1:0chỉ mục hàng
Giuseppe

@Giuseppe Đẹp. Tôi cũng sẽ xóa cái đó +;)
JAD

6

Python 3 , 72 71 byte

from numpy import*
g=lambda x,y:(dot(x[:-1],y[1:])-dot(x[1:],y[:-1]))/2

Có hai danh sách, như đã được cho phép trong các ý kiến

x = [x0,x1,x2, ...]
y = [y0,y1,y2, ...] 

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

Đây về cơ bản chỉ là việc thực hiện công thức dây giày . Tôi có thể nhận được điểm cộng cho một sân golf mà bạn thực sự sẽ thực hiện như vậy không? : D

-1, không cần một khoảng trống phía sau x,y:.



Lấy hai danh sách cũng được đề cập trong phần thân của câu hỏi ngay bây giờ :)
JAD

@JarkoDubbeldam Uh, tôi vừa thấy, rằng nó phải xuất ra khu vực. Giải pháp này hiện chỉ trả về khu vực. Điều đó có được phép không, hay nó sẽ được in?
P. Siehr

Hàm trả về giá trị được tính là đầu ra :)
JAD

Tôi nghĩ rằng với python bạn thậm chí không phải đặt tên cho hàm, vì vậy chỉ cần bắt đầu với lambda x,y:là ổn.
JAD

@JarkoDubbeldam Có quy tắc nào cho mỗi ngôn ngữ không?
P. Siehr


4

JS (ES6), 98 95 94 93 88 86 82 81 77 73 byte

(X,Y)=>{for(i in X){a+=(X[i]+X[i-1])*(Y[i]-Y[i-1]);if(!+i)a=0}return a/2}

Lấy đầu vào như thế [x1, x2, x3], [y1, y2, y3], và bỏ qua cặp tọa độ lặp lại.

-3 byte nhờ @JarkoDubbeldam

-4 byte nhờ @JarkoDubbeldam

-1 byte nhờ @ZacharyT

-4 byte nhờ @ZacharyT

-4 byte nhờ @Rick


3

J, 12 byte

Giả sử đầu vào là danh sách gồm 2 danh sách thành phần (nghĩa là bảng)

-:+/-/ .*2[\
  • 2[\ - phá vỡ nó thành Xs dây giày, nghĩa là, các ô vuông chồng lên nhau 4 elms
  • -/ .* - yếu tố quyết định của mỗi
  • +/ - tổng hợp
  • -: - chia cho 2

Nếu chúng ta nhận đầu vào dưới dạng một danh sách, trước tiên chúng ta cần chuyển đổi thành một bảng, cung cấp cho chúng ta 20 byte:

-:+/-/ .*2[\ _2&(,\)

1
"Giả sử đầu vào là danh sách gồm 2 danh sách thành phần (nghĩa là bảng)" Điều này được cho phép :)
JAD

3

MS-SQL, 66 byte

SELECT geometry::STPolyFromText('POLYGON('+p+')',0).STArea()FROM g

MS SQL 2008 và hỗ trợ cao hơn cho các chức năng / dữ liệu không gian tiêu chuẩn của Hiệp hội không gian địa lý (OGC), mà tôi đang tận dụng ở đây.

Dữ liệu đầu vào được lưu trữ trong trường p của bảng g có sẵn , theo các tiêu chuẩn đầu vào của chúng tôi .

Đầu vào là một trường văn bản với các cặp được sắp xếp theo định dạng sau: (4 4,0 1,-2 5,-6 0,-1 -4,5 -2,4 4)

Bây giờ chỉ để giải trí, nếu bạn cho phép bảng đầu vào của tôi giữ các đối tượng hình học tiêu chuẩn Mở không gian địa lý (thay vì chỉ dữ liệu văn bản), thì nó trở nên gần như không đáng kể:

--Create and populate input table, not counted in byte total
CREATE TABLE g (p geometry)
INSERT g VALUES (geometry::STPolyFromText('POLYGON((5 5, 10 5, 10 10, 5 5))', 0))

--23 bytes!
SELECT p.STArea()FROM g


0

Perl 5 -pa , 62 byte

map$\+=$F[$i]*($a[($i+1)%@a]-$a[$i++-1]),@a=eval<>}{$\=abs$\/2

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

Đưa đầu vào dưới dạng danh sách tọa độ X trên dòng đầu tiên, theo sau là danh sách tọa độ Y trên dòng thứ hai.

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.