พื้นที่ของลำเรือนูน 2 มิติ


11

คุณจะได้รับอาร์เรย์ / รายการ / เวกเตอร์ของคู่จำนวนเต็มแทนพิกัดคาร์ทีเซียนของจุดบนระนาบแบบยุคลิดแบบ 2D; พิกัดทั้งหมดอยู่ระหว่างถึงอนุญาตการทำซ้ำ ค้นหาพื้นที่ของตัวเรือนูนของจุดเหล่านั้นปัดเศษให้เป็นจำนวนเต็มที่ใกล้เคียงที่สุด จุดกึ่งกลางที่แน่นอนควรถูกปัดเศษเป็นจำนวนเต็มคู่ที่ใกล้เคียงที่สุด คุณอาจใช้ตัวเลขทศนิยมในการคำนวณระดับกลาง แต่เฉพาะในกรณีที่คุณสามารถรับประกันได้ว่าผลลัพธ์สุดท้ายจะถูกต้องเสมอ นี่คือดังนั้นโปรแกรมที่ถูกต้องที่สุดจะเป็นผู้ชนะ(x,y)-104104

เปลือกนูนของชุดของจุดเป็นชุดนูนเล็กที่สุดที่มีPบนระนาบแบบยุคลิดสำหรับจุดใดจุดหนึ่งมันคือจุดนั้น สำหรับสองจุดที่แตกต่างมันเป็นเส้นที่บรรจุพวกมันสำหรับสามจุดที่ไม่ใช่ collinear มันเป็นรูปสามเหลี่ยมที่พวกมันก่อตัวขึ้นเป็นต้นPP(x,Y)

คำอธิบายภาพที่ดีเกี่ยวกับสิ่งที่ตัวเรือนูนอธิบายได้ดีที่สุดเมื่อนึกภาพทุกจุดเหมือนตะปูบนกระดานไม้แล้วยืดแถบยางรอบตัวพวกมันเพื่อล้อมรอบทุกจุด:
ป้อนคำอธิบายรูปภาพที่นี่

กรณีทดสอบบางส่วน:

Input: [[50, -13]]
Result: 0

Input: [[-25, -26], [34, -27]]
Result: 0

Input: [[-6, -14], [-48, -45], [21, 25]]
Result: 400

Input: [[4, 30], [5, 37], [-18, 49], [-9, -2]]
Result: 562

Input: [[0, 16], [24, 18], [-43, 36], [39, -29], [3, -38]]
Result: 2978

Input: [[19, -19], [15, 5], [-16, -41], [6, -25], [-42, 1], [12, 19]]
Result: 2118

Input: [[-23, 13], [-13, 13], [-6, -7], [22, 41], [-26, 50], [12, -12], [-23, -7]]
Result: 2307

Input: [[31, -19], [-41, -41], [25, 34], [29, -1], [42, -42], [-34, 32], [19, 33], [40, 39]]
Result: 6037

Input: [[47, 1], [-22, 24], [36, 38], [-17, 4], [41, -3], [-13, 15], [-36, -40], [-13, 35], [-25, 22]]
Result: 3908

Input: [[29, -19], [18, 9], [30, -46], [15, 20], [24, -4], [5, 19], [-44, 4], [-20, -8], [-16, 34], [17, -36]]
Result: 2905

2
คุณมีกรณีทดสอบหรือไม่?
Maltysen

17
การไม่นับพื้นที่ว่างในโค้ดกอล์ฟเป็นความคิดที่ไม่ดีมันนำไปสู่การส่งข้อมูลด้วยสตริงขนาดใหญ่ของช่องว่างพร้อมรหัสทั่วไปเพื่อแปลงสตริงเป็นโค้ดและดำเนินการ
xnor

4
จุดกึ่งกลางที่แน่นอนควรถูกปัดเศษเป็นจำนวนเต็มที่ใกล้เคียงที่สุด : เพียงแค่สงสัยว่าอะไรคือเหตุผลเบื้องหลัง
Arnauld

4
[[0, 0], [1, 1], [0, 1]]1/20

6
โดยปกติแล้วความท้าทายจะอยู่ในตัวเอง แต่สิ่งนี้ไม่ใช่ คุณสามารถอธิบายได้ว่าตัวถังนูนคืออะไรและจะคำนวณอย่างไร หรือชี้ไปที่แหล่งข้อมูลอ้างอิงออนไลน์บ้าง?
Olivier Grégoire

คำตอบ:


9

SQL Server 2012+, 84 ไบต์

SELECT Round(Geometry::ConvexHullAggregate(Geometry::Point(x,y,0)).STArea(),0)FROM A

ใช้ฟังก์ชันเรขาคณิตและการรวมใน SQL Server Coordindates จากตารางAที่มีคอลัมน์และxy


9

Java 10, 405 ... ไม่พอดีอีกต่อไป; ดูประวัติการแก้ไข .. 317 316 ไบต์

P->{int n=P.length,l=0,i=0,p,q,t[],h[][]=P.clone(),s=0;for(;++i<n;)l=P[i][0]<P[l][0]?i:l;p=l;do for(h[s++]=P[p],q=-~p%n,i=-1;++i<n;q=(t[1]-P[p][1])*(P[q][0]-t[0])<(t[0]-P[p][0])*(P[q][1]-t[1])?i:q)t=P[i];while((p=q)!=l);for(p=i=0;i<s;p-=(t[0]+h[++i%s][0])*(t[1]-h[i%s][1]))t=h[i];return Math.round(.5*p/~(p%=2))*~p;}

-52 ไบต์ขอบคุณ@ OlivierGrégoire
-3 ไบต์ขอบคุณ@PeterTaylor
-7 ไบต์ขอบคุณ@ceilingcat

ลองออนไลน์

หรือ299 ไบต์โดยไม่ต้องปัดเศษ ..

คำอธิบาย:

มีสามขั้นตอนในการทำ:

  1. คำนวณคะแนนสำหรับตัวเรือนูนตามพิกัดอินพุต (โดยใช้อัลกอริทึม / การห่อของ Jarvis )
  2. คำนวณพื้นที่ของเรือนูนนี้
  3. การปัดเศษของธนาคาร ..

ในการคำนวณพิกัดที่เป็นส่วนหนึ่งของ Hve นูนเราใช้วิธีการดังต่อไปนี้:

ล.พีพีล.

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

สำหรับรหัส:

P->{                      // Method with 2D integer array as parameter & long return-type
  int n=P.length,         //  Integer `n`, the amount of points in the input
      l=0,                //  Integer `l`, to calculate the left-most point
      i=0,                //  Index-integer `i`
      p,                  //  Integer `p`, which will be every next counterclockwise point
      q,                  //  Temp integer `q`
      t[],                //  Temp integer-array/point
      h[][]=P.clone(),    //  Initialize an array of points `h` for the Convex Hull
      s=0;                //  And a size-integer for this Convex Hull array, starting at 0
  for(;++i<n;)            //  Loop `i` in the range [1, `n`):
    l=                    //   Change `l` to:
      P[i][0]<P[l][0]?    //   If i.x is smaller than l.x:
       i                  //    Replace `l` with the current `i`
      :l;                 //   Else: leave `l` unchanged
  p=l;                    //  Now set `p` to this left-most coordinate `l`
  do                      //  Do:
    for(h[s++]=P[p],      //   Add the `p`'th point to the 2D-array `h`
        q=-~p%n,          //   Set `q` to `(p+1)` modulo-`n`
        i=-1;++i<n;       //    Loop `i` in the range [0, `n`):
        ;q=               //      After every iteration: change `q` to:
                          //       We calculate: (i.y-p.y)*(q.x-i.x)-(i.x-p.x)*(q.y-i.y), 
                          //       which results in 0 if the three points are collinear;
                          //       a positive value if they are clockwise;
                          //       or a negative value if they are counterclockwise
           (t[1]-P[p][1])*(P[q][0]-t[0])<(t[0]-P[p][0])*(P[q][1]-t[1])?
                          //       So if the three points are counterclockwise:
            i             //        Replace `q` with `i`
           :q)            //       Else: leave `q` unchanged
      t=P[i];             //     Set `t` to the `i`'th Point (to save bytes)
  while((p=q)             //  And after every while-iteration: replace `p` with `q`
             !=l);        //  Continue the do-while as long as `p` is not back at the
                          //  left-most point `l` yet
  // Now step 1 is complete, and we have our Convex Hull points in the List `h`

  for(p=i=0;              //  Set `p` (the area) to 0
      i<s                 //  Loop `i` in the range [0, `s`):
      ;p-=                //    After every iteration: Decrease the area `p` by:
        (t[0]+h[++i%s][0])//     i.x+(i+1).x
        *(t[1]-h[i%s][1]))//     Multiplied by i.y-(i+1).y
    t=h[i];               //   Set `t` to the `i`'th point (to save bytes)
 return Math.round(.5*p/~(p%=2))*~p;}
                          //  And return `p/2` rounded to integer with half-even

1
ขอให้เรายังคงอภิปรายนี้ในการแชท
Kevin Cruijssen


6

JavaScript (ES6),  191  189 ไบต์

ใช้Jarvis march (อัลกอริทึมห่อของขวัญ)

P=>(r=(g=p=>([X,Y]=P[p],Y*h-X*v)+(P.map(([x,y],i)=>q=(y-Y)*(P[q][0]-x)<(x-X)*(P[q][1]-y)?i:q,q=P[++p]?p:0,h=X,v=Y)|q?g(q):V*h-H*v))(v=h=0,([[H,V]]=P.sort(([x],[X])=>x-X)))/2)+(r%1&&r&1)/2|0

ลองออนไลน์!

หรือ170 ไบต์โดยไม่มีรูปแบบการปัดเศษที่ยุ่งยาก


การปัดเศษเป็นแค่ปลาเฮอริ่งแดงเพราะสองเท่าของพื้นที่นั้นเป็นจำนวนเต็มเสมอ
Vladimir Reshetnikov

4
@VladimirReshetnikov จากความอยากรู้: ถ้าคุณรู้ว่าการปัดเศษเป็นปลาเฮอริ่งแดงทำไมต้องเพิ่มมันให้หันเหความสนใจจากความท้าทายที่ดีเป็นอย่างนั้น? .. ไม่ใช่ทุกภาษาที่สร้างการปัดเศษของ Banker ไม่ใช่ภาษาที่รู้จักกันดี ผมชอบความท้าทายในการทั่วไปและสนุกกับการเขียนคำตอบ Java ของฉัน แต่ปัดเศษและการขาดการอธิบายสิ่งที่นูนฮัลล์คือการทำให้ความท้าทายอยู่ในตัวเองเหลือเกินฉันจาก upvoting มัน TBH .. PS: ขออภัย@Arnauldการทำเช่นนี้เป็น แสดงความคิดเห็นในคำตอบของคุณ ..
Kevin Cruijssen

4

R , 85 81 78 ไบต์

function(i,h=chull(i),j=c(h,h[1]))round((i[h,1]+i[j[-1],1])%*%diff(-i[j,2])/2)

ลองออนไลน์!

จะเข้าเป็นเมทริกซ์ 2 คอลัมน์ - ครั้งแรกที่สองสำหรับx yR ของroundจริงใช้วิธีการปัดเศษของนายธนาคารเพื่อให้เรามีค่อนข้างโชคดีที่นี่

Σผม(xผม-1+x)(Yผม-1-Yผม)/2

ขอบคุณ Giuseppe สำหรับ -3 ไบต์


3

[R + sp แพ็คเกจ], 55 ไบต์

function(x)round(sp::Polygon(x[chull(x),,drop=F])@area)

ลองใช้ที่ RDRR

ฟังก์ชั่นที่ใช้เมทริกซ์ anx 2 และส่งคืนพื้นที่ที่ถูกปัดเศษ สิ่งนี้ใช้spแพ็คเกจ drop=Fเป็นสิ่งจำเป็นที่จะจัดการกับกรณีหนึ่งประสาน RDRR ใช้สำหรับการสาธิตเนื่องจาก TIO ขาดspแพ็คเกจ

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