İki üçgenin kesişimi


19

2D düzlemde 4 puan verilen A, B, C, D, kesişim üçgenler bölgenin alanının hesaplanması OABve OCD, Okoordine olan uçağın merkezidir (0, 0).

Sabit zaman karmaşıklığında çalışan algoritmalar (aritmetik işlemler açısından) teşvik edilir, ancak zorlanmaz.

kurallar

  • Her nokta iki gerçek sayı olarak temsil edilir, X ve Y koordinatlarını gösterir.
    • İsteğe bağlı olarak, programlama dilinizde (veya programlama dilinizin bir kütüphanesinde) yerleşik Pointtip veya eşdeğeri varsa, Pointnesneyi giriş olarak almasına izin verilir .
  • Giriş, aşağıdakiler dahil ancak bunlarla sınırlı olmamak üzere, formatlarda 4 puan olarak verilir:
    • 8 koordinat listesi.
    • 4 puanlık bir liste, her nokta herhangi bir uygun biçimde temsil edilebilir.
    • 2 puanlık iki liste.
    • vb.
  • Noktaların belirli bir düzenini kabul edemezsiniz (saat yönünün tersine veya saat yönünde)
  • Noktanın Ogirdi olarak geçtiğini varsayamazsınız. Başka bir deyişle, program harici girdi almamalı ve kullanmamalıdır.
  • Tüm noktaların farklı olduğunu varsayamazsınız. Başka bir deyişle, üçgenler dejenere olabilir. Bu durumu da ele almanız gerekir (aşağıdaki test senaryolarına bakın)
  • Mutlak veya bağıl fark, aşağıdaki örnek test durumlarından daha az olmalıdır .10-3

Kazanma kriterleri

Bu , bayt kazanmak en kısa cevap!

Örnek test senaryoları

Ax Ay Bx By Cx Cy Dx Dy area

5 1 1 3 -1 0 0 -1 0
5 1 1 3 -1 0 0 0 0
5 1 1 3 0 0 0 0 0
5 1 1 3 3 4 4 -3 4.50418
5 1 1 3 1 2 2 1 1.5
5 1 1 3 -2 5 4 -2 1.74829
5 1 1 3 -2 5 5 4 2.96154
5 1 1 3 3 5 5 4 1.88462
5 1 1 3 3 5 3 1 3.92308
5 1 1 3 3 5 4 -1 5.26619
5 1 1 3 5 1 4 -1 0
5 1 1 3 5 1 1 3 7
1 3 1 3 5 1 1 3 0
1 3 1 3 1 3 1 3 0
4 8 4 -1 -2 6 -2 -3 0

1.2 3.4 -0.3 4.2 5 7.6 -1.1 2.4 2.6210759326188535
3.1 0.6 0.1 7.2 5.2 0.7 0.9 8 9.018496993987977

İsteyen varsa, ilk test örneği grubu için çıktılar tam olarak aşağıda verilmiştir:

0
0
0
46375/10296
3/2
1792/1025
77/26
49/26
51/13
23345/4433
0
7
0
0
0

Test durumu için örnek resim 5 1 1 3 3 4 4 -3(yeşil dörtgen alan beklenen çıktıdır):

[ görüntü]


Test durumlarınızdan birinin 8 yerine 9 girişi vardır. 1.2 3.4 -0.3 4.2 5 3 7.6 -1.1 2.4 0
Kelly Lowder

1
@KellyLowder Düzeltildi.
user202729

Yanıtlar:


16

Wolfram Dili (Mathematica) , 55 bayt

0&@@Area@BooleanRegion[And,Simplex[{0{,}}~Join~#]&/@#]&

Çevrimiçi deneyin!

Önemsiz cevap birkaç bayt traş.

%@{{{5, 1}, {1, 3}}, {{3, 4}, {4, -3}}} yields 46375/10296 or 4.504176379

Değiştirme Areaile DiscretizeRegionkesişim gösterecektir.

resim açıklamasını buraya girin

Bu arada, bu sadece üçgenlerle değil, herhangi bir simpleks ile çalışacaktır.

-1 Bayt, JungHwan Min sayesinde

@ user202729'un önerisi 4 bayt ekledi, ancak dejenere üçgenler için 0 verimi verdi


1
Poligon yerine Simplex de kullanılabilir
Kelly Lowder

1
Bir bayt daha: {{0,0}}- {0{,}}(bu, ifadenin değerlendirdiği için çalışır {Times[0, {Null, Null}]})
JungHwan Min

Örnek test durumlarında listelenen bu test durumu için başarısız olun .
user202729

Zaten bunun TIO üzerinde çalışmadığını belirtti. Kaputun altında ne olduğundan emin değilim.
Kelly Lowder

1
İki çizginin kesişimi için işe yaramadığını görüyorum. Bu test çantasını atlamaktan kötüyüm. Teknik olarak bunlar üçgen değil. Sanırım bu tekniği alacaksak, belki de yazının başlığını ve ilk cümleyi değiştirmelisiniz. Ayrıca alanın tek boyutlu bir nesne için tanımlanıp tanımlanmadığı hakkında gerçekten ezoterik bir tartışma yapabiliriz, ama istemem.
Kelly Lowder

5

Piton 2 + jul, 341 318 313 284 270 bayt

Bay Xcoder sayesinde derhal TIO -23 baytlarına PIL ekleyen Dennis'e özel teşekkürler

import PIL.Image as I,PIL.ImageDraw as D
l=[i*1000for i in[0,0]+input()+[0,0]]
z=zip(*[[i-min(t)for i in t]for t in l[::2],l[1::2]])
print sum(map(int.__mul__,*map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),map(I.new,'11',[[max(l)-min(l)]*2]*2),[z[:3],z[3:]])))/1e6

Çevrimiçi deneyin! veya Tüm test senaryolarını deneyin

Farkı hesaplamak için bu kelimenin tam anlamıyla üçgenleri çizin ve her iki görüntüde boyanmış piksel miktarını kontrol edin.
Bu yöntem, görüntü boyutunu artırarak yumuşatılan bir yuvarlama hatası ekledi.

açıklama

#the image/triangles are enlarged to increase the precision
#a pair of zeros are inserted in the start and at the end, this way "l" will have all 6 points to draw the triangles 
l=[i*1000for i in[0,0]+input()+[0,0]]
#split the input in x and y, where x=l[::2] and y=l[1::2]
#get the smallest number on each list, that will be "0" if there is no negative number, to be used as offset.
#this will be used to overcome the fact that PIL won't draw on negative coords
#zip "x" and "y" lists, to create a list containing the points
z=zip(*[[i-min(t)for i in t]for t in x,y])
#create 2 (B&W) blank images
#where the size is the difference between the smallest and the largest coord.
map(I.new,'11',[[max(l)-min(l)]*2]*2)
#draw both triangles and return the pixel list of each image
map(lambda i,c:D.Draw(i).polygon(c,1)or i.getdata(),<result of previous line>,[z[:3],z[3:]])
#count the amount of overlapping pixels by summing the color of each pixel, if the pixel is "1" in both images, then the triangles are overlapping, then the amount of pixels is divided by the initial enlarging factor squared (1e6)
print sum(map(int.__mul__,*<result of previous line>))/1e6
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.