Bu çokgenin alanı nedir?


19

Bir çokgenin alanını hesaplayın.

Bu ayakkabı bağı algoritması videosundan esinlenmiştir.

Görev

İşiniz, bir çokgenin alanını hesaplayan bir program veya işlev oluşturmaktır. Program veya işlev meta'daki varsayılan tanıma göre tanımlanır.

Giriş

Çokgenin her bir tepe noktasının X ve Y koordinatlarını alacaksınız. Girişi tuples ( [[x1, y1], [x2, y2], etc]), matris veya düz liste ( [x1, y1, x2, y2, etc]) olarak alabilirsiniz. Sırasıyla iki koordinat içeren liste xve ykoordinatlar da kullanılabilir. Köşeler saat yönünün tersine numaralandırılmıştır ve ilk tepe noktası, sağlanan son tepe noktasıyla aynıdır, böylece çokgeni kapatır.

İsterseniz girişi son köşe noktası olmadan alabilirsiniz (bu nedenle her bir koordinatı yalnızca bir kez alın).

Çokgenlerin kenarlarının kesişmediğini varsayabilirsiniz. Ayrıca tüm köşelerin tamsayı koordinatları olduğunu varsayabilirsiniz.

Çıktı

Çokgenin alanı. Tüm standart çıktı yöntemlerine izin verilir. Diliniz kayan bölüme izin vermiyorsa ve çözüm bir tamsayı değilse, bir kesir döndürmenize izin verilir. Kesirin basitleştirilmesi zorunlu değildir, bu nedenle geri 2/4dönüşe izin verilir.

Kazanma kriteri

En kısa kod kazanır!

Test senaryoları

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

resim açıklamasını buraya girin

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

resim açıklamasını buraya girin


Girişe [x1, x2, x3], [y1, y2, y3]izin veriliyor mu?
programmer5000

@ programmer5000 ve Martin Ender, evet, içinde düzenleyeceğim :)
JAD

Katılıyorum, yeniden açmak için oy kullandı.
programmer5000

1
@flawr Bunu bir çift yaptım. Burada olduğu gibi aynı yöntemi özyinelemeli olarak uygulamak, çapraz noktaları olan ve sonuçta elde edilen alt kümeleri saat yönünün tersine bir şekilde sıralamayı gerektiren köşeleri bulmayı gerektirecek olan dupe hedefinin bir dupe'si değildir - bu çok daha karmaşık görünüyor.
Jonathan Allan

Yanıtlar:


13

Jöle ,  8  6 bayt

Emigna sayesinde -1 bayt (yedek , ÆḊ2 derinliğe sahiptir)
Emigna sayesinde -1 bayt, tekrar (yarıya, Hkayan nokta gerekmez ÷2)

ṡ2ÆḊSH

Örneklere göre (bir tekrar ile) koordinat çiftlerinin listesini saat yönünde alan ve alanı döndüren monadik bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

Ayakkabı bağı algoritmasını, tıpkı videoda açıklandığı gibi uygular (ki geçen gün de izledim!)

ṡ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

İkinci test senaryosu benim için "-0.5" döndürüyor: o
JAD

Oh, kontrol etmem gerekecek ...
Jonathan Allan

Çünkü [x,y]koordinatlar saat yönünün tersine değil saat yönünde verilir. Girişi [[1,1],[0,1],[1,0],[1,1]]geri döner 0.5.
Jonathan Allan

1
Woops, şunu düzenleyeceğim: D
JAD

1
Ayrıca, Hyerine÷2
Emigna



16

JavaScript (ES6), 69 67 47 bayt

@Rick sayesinde, köşelerin saat yönünün tersine sıralanması garanti edilirse ve düz bir listeyi girdi olarak almayı önermek için mutlak değere ihtiyacımız olmadığını fark ettiğiniz için 20 bayt tasarruf edin!

Girdiyi, son köşe dahil düz bir köşe listesi olarak alır.

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

Çevrimiçi deneyin!

Nasıl?

n

area=|(x0y1y0x1)+(x1y2y1x2)++(xn1y0yn1x0)2|


Çok etkileyici! Nasıl çalıştığını açıklayabilir misiniz?
Rugnir

İkinci test durumundaki köşe noktaları yanlışlıkla yanlış sıralanmıştır. Abs gerekli olmamalıdır.
Rick

Ayrıca düz bir listeye geçiş yaparak 7 bayt kaydedebilirsiniz:a=>(g=([x,y,...a])=>1-a?0:x*a[1]-y*a[0]+g(a))(a)/2
Rick

@Rick haklı - abs gerekli değil. Bu olmadan formül işaretli alanı hesaplar, bu da pozitiftir, çünkü köşeler saat yönünün tersine verilir.
Angs

@ Teşekkürler! Güncellendi ... 10 ay sonra: /
Arnauld

7

R, 54 52 bayt

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

Hangi işlevi değerlendirir:

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

Önceden tanımlanmış olanları kullanır F = FALSE = 0 . Bağlı videoda ayakkabı bağı algoritmasını uygular :)

Giuseppe sayesinde -2 bayt


i+-1:0Sıra endeksi olarak -1 bayt
Giuseppe

@Giuseppe Nice. Ben de kaldıracağım +;)
JAD

6

Python 3 , 72 71 bayt

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

Yorumlarda izin verildiği gibi iki liste alır

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

Çevrimiçi deneyin!

Bu temelde sadece ayakkabı bağı formülünün uygulanmasıdır . Aslında uygulayacağınız bir golf için artı puan alabilir miyim? : D

-1, arkasında boşluk bırakmaya gerek yok x,y:.



Sorunun ana
JAD

@JarkoDubbeldam Uh, az önce gördüm, bölgeyi çıkarmak zorunda. Bu çözüm şu anda alanı döndürüyor. Buna da izin veriliyor mu yoksa yazdırılmalı mı?
P. Siehr

Bir değer döndüren işlev çıktı olarak sayılır :)
JAD

Bence python ile fonksiyonu isimlendirmenize bile gerek yok, bu yüzden sadece başlamak lambda x,y:iyi.
JAD

@JarkoDubbeldam Her dil için herhangi bir yerde kural var mı?
P. Siehr


4

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

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

Gibi girdi alır [x1, x2, x3], [y1, y2, y3]ve tekrarlanan koordinat çiftini atlar.

@JarkoDubbeldam sayesinde -3 bayt

@JarkoDubbeldam sayesinde -4 bayt

@ZacharyT sayesinde -1 bayt

@ZacharyT sayesinde -4 bayt

@Rick sayesinde -4 bayt


3

J, 12 bayt

Girdinin 2 öğe listesinin (yani bir tablo) olduğu varsayılarak

-:+/-/ .*2[\
  • 2[\ - ayakkabı bağı X'lere ayırır, yani 4 elmsin üst üste binen kareleri
  • -/ .* - her birinin belirleyicisi
  • +/ - topla
  • -: - 2'ye böl

Girdiyi tek bir liste olarak alırsak, önce bize 20 bayt vererek bir tabloya dönüştürmemiz gerekir:

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

1
"Girdinin 2 öğe listesinin bir listesi olduğu varsayıldığında (yani, bir tablo)" Buna izin verilir :)
JAD

3

MS-SQL, 66 bayt

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

MS SQL 2008 ve üstü, buradan faydalandığım Open Geospatial Consortium (OGC) -standart mekansal veri / fonksiyon desteği.

Girdi verileri alanına depolanır p önceden var olan Tablo g , bizim giriş standartlarına göre .

Girdi, sıralı çiftlerin aşağıdaki biçimde olduğu bir metin alanıdır: (4 4,0 1,-2 5,-6 0,-1 -4,5 -2,4 4)

Şimdi sadece eğlence için, giriş tablomun Open Geospatial Consortium standart geometri nesnelerini (yalnızca metin verileri yerine) tutmasına izin verdiyseniz , neredeyse önemsiz hale gelir:

--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 bayt

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

Çevrimiçi deneyin!

Girişi ilk satırdaki X koordinatlarının, ardından ikinci satırdaki Y koordinatlarının bir listesi olarak alır.

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.