2D konveks gövdenin alanı


11

Size bir 2D Öklid düzlemindeki noktaların kartezyen koordinatlarını (x,y) temsil eden tam sayı çiftlerinden oluşan bir dizi / liste / vektör verilir ; tüm koordinatlar -104 ile 104 , kopyalara izin verilir. En yakın tam sayıya yuvarlanmış bu noktaların dışbükey gövdesinin alanını bulun ; tam bir orta nokta en yakın çift tam sayıya yuvarlanmalıdır. Ara hesaplarda kayan nokta sayıları kullanabilirsiniz, ancak yalnızca nihai sonucun her zaman doğru olacağını garanti ederseniz. Bu , bu yüzden en kısa doğru program kazanır.

Dışbükey noktaları bir dizi P içeren en küçük konveks dizi P . Öklid düzleminde, herhangi bir tek nokta için (x,y) , noktanın kendisidir; iki ayrı nokta için, onları içeren çizgidir, üç doğrusal olmayan nokta için, oluşturdukları üçgendir, vb.

Dışbükey bir gövdenin ne olduğuna dair iyi bir görsel açıklama, en iyi şekilde tüm noktaları ahşap bir tahtada çivi olarak hayal etmek ve daha sonra tüm noktaları çevrelemek için etraflarında bir lastik bant germek olarak tanımlanır:
resim açıklamasını buraya girin

Bazı test örnekleri:

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
Test durumunuz var mı?
Maltysen

17
Kod golfünde boşluk saymamak kötü bir fikirdir, dizeyi koda dönüştürmek ve yürütmek için büyük boşluklar ve genel kod içeren gönderilere yol açar.
xnor

4
tam bir orta nokta en yakın çift tam sayıya yuvarlanmalıdır : sadece bunun ardındaki mantık nedir?
Arnauld

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

6
Genellikle zorluklar kendi kendine yetir, ama bu değil. Dışbükey bir gövdenin ne olduğunu ve nasıl hesaplanacağını açıklayabilir misiniz? Veya bazı çevrimiçi referans kaynaklarına mı işaret ediyorsunuz?
Olivier Grégoire

Yanıtlar:


9

SQL Server 2012+, 84 bayt

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

SQL Server'da geometri fonksiyonlarını ve toplamalarını kullanır. Koordinatlar Asütun xve içeren tablodan alınmıştır y.


9

Java 10, 405 ... artık sığmadı; düzenleme geçmişine bakın .. 317 316 bytes

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 sayesinde bayt @ OlivierGrégoire
-3 sayesinde bayt @PeterTaylor
-7 sayesinde bayt @ceilingcat

Çevrimiçi deneyin.

Veya 299 yuvarlama olmadan bayt .. .

Açıklama:

Yapmanız gereken üç adım vardır:

  1. Convex Gövdesi için noktaları giriş koordinatlarına göre hesaplayın ( Jarvis Algoritması / Sarma kullanarak )
  2. Bu Konveks Gövdenin alanını hesaplayın
  3. Bankacının yuvarlanması ..

Convex Gövdesinin bir parçası olan koordinatları hesaplamak için aşağıdaki yaklaşımı kullanırız:

lppl

resim açıklamasını buraya girin

Kod gelince:

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



6

JavaScript (ES6),  191  189 bayt

Jarvis yürüyüşünü uygular (hediye sarma algoritması olarak da bilinir).

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

Çevrimiçi deneyin!

Veya hantal yuvarlama şeması olmadan 170 bayt .


Yuvarlama sadece kırmızı bir ringa balığıydı çünkü alanın iki katı daima tamsayıdır.
Vladimir Reshetnikov

4
@VladimirReshetnikov Merak ettiyse: Yuvarlamanın kırmızı bir ringa balığı olduğunu biliyorsan, neden aksi takdirde iyi bir meydan okumadan uzaklaşmak için onu eklemelisin? Maalesef: Genel olarak meydan okuma gibi I ve tbh .. PS, benim Java cevap yazma, ancak yuvarlama ve Konveks Hull meydan kendine yeten bunu upvoting beni kaçındı yapmak ne açıklama eksikliği zevk @Arnauld bir şekilde bunu yapmak için Cevabınıza yorum yapın ..
Kevin Cruijssen

4

R , 85 81 78 bayt

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

Çevrimiçi deneyin!

Girdiyi 2 sütunlu bir matris olarak alır - birincisi x, ikincisi y. R var roundbiz burada oldukça şanslı böylece aslında, bankerin yuvarlama yöntemini kullanır.

Σben(xben-1+x)(yben-1-yben)/2

Giuseppe'ya -3 bayt için teşekkürler.


3

[R + sp paketi], 55 bayt

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

RDRR'de deneyin

Anks 2 matrisini alan ve yuvarlatılmış alanı döndüren bir işlev. Bu sppaketi kullanır . Bir drop=Fkoordinat davasını ele almak için gereklidir. TIO sppaketten yoksun olduğu için demo için kullanılan RDRR .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.