พื้นที่ของรูปหลายเหลี่ยมนี้คืออะไร


19

คำนวณพื้นที่ของรูปหลายเหลี่ยม

แรงบันดาลใจจากวิดีโออัลกอริทึมเชือกผูกรองเท้า

งาน

งานของคุณคือการสร้างโปรแกรมหรือฟังก์ชั่นที่คำนวณพื้นที่ของรูปหลายเหลี่ยม โปรแกรมหรือฟังก์ชั่นถูกกำหนดตามคำนิยามเริ่มต้นในเมตาดาต้า

อินพุต

คุณจะได้รับพิกัด X และ Y ของแต่ละจุดยอดของรูปหลายเหลี่ยม คุณสามารถรับอินพุตเป็นรายการของ tuples ( [[x1, y1], [x2, y2], etc]), เมทริกซ์หรือรายการแบน ( [x1, y1, x2, y2, etc]) อนุญาตให้มีสองรายการประกอบด้วยxและyพิกัดตามลำดับ จุดยอดมีหมายเลขทวนเข็มนาฬิกาและจุดสุดยอดแรกจะเหมือนกับจุดสุดยอดที่ให้ไว้ดังนั้นปิดรูปหลายเหลี่ยม

หากคุณต้องการคุณสามารถป้อนข้อมูลโดยไม่มีจุดสุดยอดครั้งสุดท้าย (ดังนั้นรับแต่ละพิกัดเพียงครั้งเดียว)

คุณสามารถสันนิษฐานได้ว่าขอบของรูปหลายเหลี่ยมไม่ได้ตัดกัน คุณสามารถสันนิษฐานได้ว่าจุดยอดทั้งหมดมีพิกัดจำนวนเต็ม

เอาท์พุต

พื้นที่ของรูปหลายเหลี่ยม อนุญาตวิธีการส่งออกมาตรฐานทั้งหมด หากภาษาของคุณไม่อนุญาตให้มีการหารแบบลอยตัวและวิธีแก้ปัญหาจะไม่ใช่จำนวนเต็มคุณได้รับอนุญาตให้ส่งคืนเศษส่วน ไม่จำเป็นต้องทำให้เศษส่วนเรียบง่ายดังนั้น2/4จะอนุญาตให้ส่งคืนได้

เกณฑ์การชนะ

รหัสที่สั้นที่สุดชนะ!

กรณีทดสอบ

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

ป้อนคำอธิบายรูปภาพที่นี่

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

ป้อนคำอธิบายรูปภาพที่นี่


[x1, x2, x3], [y1, y2, y3]อนุญาตให้ป้อนข้อมูลเหมือนหรือไม่
programmer5000

@ programmer5000 และ Martin Ender ใช่ฉันจะแก้ไขใน :)
JAD

ฉันเห็นด้วยโหวตให้เปิดใหม่
programmer5000

1
@ flawr ฉันทำอย่างนั้นล่อลวงจากนี้ ไม่ใช่การล่อลวงเป้าหมายของการล่อลวงซึ่งการใช้วิธีการเดียวกับที่นี่ซ้ำ ๆ จะต้องค้นหาจุดยอดที่เป็นจุดผ่านและจะต้องสั่งให้เซตย่อยที่ได้มาเป็นแบบทวนเข็มนาฬิกา - ซึ่งดูซับซ้อนกว่ามาก
Jonathan Allan

คำตอบ:


13

เยลลี่ ,  8  6 ไบต์

-1 ขอบคุณไบต์ Emigna (ซ้ำซ้อน, ÆḊมีซ้ายลึกของ 2)
-1 ขอบคุณไบต์ Emigna อีกครั้ง (ครึ่ง, Hเป็นจุดลอยไม่จำเป็นต้อง÷2)

ṡ2ÆḊSH

ลิงก์ monadic ที่ใช้รายการคู่ของพิกัดตามเข็มนาฬิกาตามตัวอย่าง (ด้วยการซ้ำหนึ่งครั้ง) และส่งคืนพื้นที่

ลองออนไลน์!

อย่างไร?

ใช้อัลกอริทึมเชือกผูกรองเท้าตามที่อธิบายไว้ในวิดีโอ (ซึ่งฉันบังเอิญได้ดูเมื่อวันก่อนด้วย!)

ṡ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

กรณีทดสอบที่สองส่งคืน `-0.5 'สำหรับฉัน: o
JAD

โอ้ฉันจะต้องตรวจสอบ ...
Jonathan Allan

นั่นเป็นเพราะ[x,y]พิกัดพวกเขาได้รับตามเข็มนาฬิกามากกว่าทวนเข็มนาฬิกา การป้อนข้อมูลของจะกลับ[[1,1],[0,1],[1,0],[1,1]] 0.5
Jonathan Allan

1
ว้าวฉันจะแก้ไขนั่น: D
JAD

1
นอกจากนี้Hแทน÷2
Emigna

29

Mathematica ขนาด 13 ไบต์

Area@*Polygon

มันจะได้รับเพิ่มเติมเล็กน้อย
นาย Xcoder


o_O - ฉันตั้งใจจริง ๆ ...
นาย Xcoder

3
นั่นคือ Mathematica สำหรับคุณ ทุกสิ่งที่เป็นไปได้ถูกสร้างขึ้นในภาษา
Brian Minton


16

JavaScript (ES6), 69 67 47 ไบต์

ขอขอบคุณ @Rick ที่สังเกตเห็นว่าเราไม่จำเป็นต้องมีค่าสัมบูรณ์หากจุดยอดถูกรับประกันว่าจะเรียงตามลำดับทวนเข็มนาฬิกาและสำหรับการแนะนำให้ใช้รายการแบบแบนเป็นอินพุตช่วยประหยัด 20 ไบต์!

รับอินพุตเป็นรายการแบนของจุดยอดรวมถึงจุดสุดยอดสุดท้าย

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

ลองออนไลน์!

อย่างไร?

n

aRอีa=|(x0Y1-Y0x1)+(x1Y2-Y1x2)+...+(xn-1Y0-Yn-1x0)2|


ที่น่าประทับใจมาก! คุณอธิบายได้ไหมว่ามันทำงานอย่างไร
Rugnir

จุดยอดในกรณีทดสอบที่สองถูกสั่งผิดอย่างไม่ถูกต้อง หน้าท้องไม่ควรจำเป็น
Rick

นอกจากนี้คุณยังสามารถบันทึก 7 ไบต์สลับเป็นรายการแบบเรียบง่ายได้ด้วย:a=>(g=([x,y,...a])=>1-a?0:x*a[1]-y*a[0]+g(a))(a)/2
Rick

@Rick นั้นถูกต้อง - abs ไม่จำเป็น หากไม่มีสูตรคำนวณพื้นที่ที่ลงนามซึ่งเป็นค่าบวกเพราะได้รับจุดยอดตามลำดับทวนเข็มนาฬิกา
อัง

@Rick ขอบคุณ! อัปเดต ... ประมาณ 10 เดือนต่อมา: /
Arnauld

7

R, 54 52 ไบต์

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

ซึ่งประเมินการทำงาน:

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

F = FALSE = 0ทำให้การใช้ที่กำหนดไว้ล่วงหน้า ใช้อัลกอริทึมเชือกผูกรองเท้าในวิดีโอที่เชื่อมโยง :)

-2 ไบต์ขอบคุณ Giuseppe


-1 ไบต์สำหรับi+-1:0เป็นดัชนีแถว
Giuseppe

@Giuseppe Nice ฉันจะลบ+เช่นกัน;)
JAD

6

Python 3 , 72 71 ไบต์

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

ใช้สองรายการตามที่ได้รับอนุญาตในความคิดเห็น

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

ลองออนไลน์!

นี่เป็นเพียงการดำเนินการตาม เชือกผูกรองเท้าสูตร ฉันขอคะแนนบวกสำหรับกอล์ฟที่คุณจะใช้จริงหรือไม่? : D

-1 x,y:มีความจำเป็นในการที่อยู่เบื้องหลังไม่มีช่องว่าง



มีการพูดถึงสองรายการในเนื้อหาของคำถามในตอนนี้ :)
JAD

@ JarkoDubbeldam เอ่อฉันเพิ่งเห็นว่ามันต้องออกพื้นที่ ขณะนี้โซลูชันนี้เพิ่งคืนพื้นที่ ที่ได้รับอนุญาตเช่นกันหรือจะพิมพ์?
P. Siehr

ฟังก์ชันที่ส่งคืนค่าจะนับเป็นเอาต์พุต :)
JAD

ฉันคิดว่าด้วย python คุณไม่จำเป็นต้องตั้งชื่อฟังก์ชั่นดังนั้นเพียงแค่เริ่มต้นด้วยlambda x,y:ก็ดี
JAD

@JarkoDubbeldam มีกฎสำหรับแต่ละภาษาไหม?
P. Siehr


4

JS (ES6), 98 95 94 93 88 86 82 81 77 73 73 ไบต์

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

ใช้อินพุตเหมือน [x1, x2, x3], [y1, y2, y3]และข้ามคู่ coord ที่ซ้ำกัน

-3 ไบต์ขอบคุณ @JarkoDubbeldam

-4 ไบต์ขอบคุณ @JarkoDubbeldam

-1 ไบต์ขอบคุณ @ZacharyT

-4 ไบต์ขอบคุณ @ZacharyT

-4 ไบต์ขอบคุณ @Rick


3

J, 12 ไบต์

สมมติว่าอินพุตเป็นรายการของ 2 รายการองค์ประกอบ (เช่นตาราง)

-:+/-/ .*2[\
  • 2[\ - แบ่งมันออกเป็น Shselace Xs เช่นทับซ้อนกันสี่เหลี่ยมของ 4 elms
  • -/ .* - ปัจจัยของแต่ละ
  • +/ - รวมมัน
  • -: - หารด้วย 2

หากเราได้รับอินพุตเป็นรายการเดียวเราต้องเปลี่ยนเป็นตารางก่อนโดยให้ 20 ไบต์แก่เรา:

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

1
"สมมติว่าเข้าเป็นรายการที่ 2 แสดงองค์ประกอบ (เช่นตาราง) เป็น" นี้ได้รับอนุญาต :)
JAD

3

MS-SQL, 66 ไบต์

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

MS SQL 2008 และสูงกว่ารองรับ Open Geospatial Consortium (OGC) ข้อมูล / ฟังก์ชั่นเชิงพื้นที่ที่เป็นมาตรฐานซึ่งฉันได้รับประโยชน์จากที่นี่

การป้อนข้อมูลจะถูกเก็บไว้ในสนามพีของที่มีอยู่ก่อนตารางกรัม , ตามมาตรฐานการป้อนข้อมูลของเรา

อินพุตเป็นฟิลด์ข้อความที่มีคู่ที่สั่งในรูปแบบต่อไปนี้: (4 4,0 1,-2 5,-6 0,-1 -4,5 -2,4 4)

ตอนนี้ก็เพื่อความสนุกถ้าคุณอนุญาตให้ตารางอินพุตของฉันถือวัตถุเรขาคณิตมาตรฐาน Open Geospatial Consortium (แทนที่จะเป็นเพียงแค่ข้อมูลตัวอักษร) มันจะกลายเป็นเรื่องเล็กน้อย:

--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 ไบต์

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

ลองออนไลน์!

รับอินพุตเป็นรายการของพิกัด X ในบรรทัดแรกตามด้วยรายการของพิกัด Y ในวินาที

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.