Bir yol bölümü gibi; ilk kez dokundu


14

2 veya daha fazla 2B kartezyen noktadan oluşan sıralı bir liste verildiğinde, yol kendisine dokunursa veya kendiliğinden kesişirse gerçek bir değer üretir; aksi taktirde kendisine dokunmuyorsa veya kendiliğinden kesişmiyorsa bir falsy değeri verin.

Listedeki ardışık noktaların farklı olduğunu varsayabilirsiniz.

Örnekler:

(0,0), (1,0) -> falsey
(0,0), (1,0), (0,0) -> truthy
(0,0), (1,0), (1,1), (0,0) -> truthy
(0,0), (2,0), (1,1), (1,-1) -> truthy
(0,0), (10,0), (0,1), (10,1), (0,2), (10,2) -> falsey

Burada verdiğim tüm koordinatların tamsayı olduğuna dikkat edin. {İnteger, ondalık, rasyonel, kayan nokta, ...} dışında istediğiniz her şeyin koordinat girişlerini destekleyebilirsiniz. Ancak uygulama hesaplamalarınız verilen girdiler için doğru cevapları vermelidir.


4
ne iyi bir başlık A +
undergroundmonorail

İlk sahne ait Rezervuar Köpekleri isteyen?
Luis Mendo

Yanlış anlıyorsam beni affet ama son test davası nasıl kesişmiyor? i.imgur.com/wiNMByd.png
totallyhuman

2
@icrieverytim Kapalı bir yürüyüş değil. Son nokta birinciye bağlanmaz.
HyperNeutrino

Yanıtlar:


5

Python 2 , 315 309 298 382 380 372 bayt

s=sorted
w=lambda(x,y),(X,Y),(z,w):(X-x)*(w-y)-(z-x)*(Y-y)
def I(a,b):p,q=s(a);P,Q=s(b);n,N,m,M=w(p,q,P),w(p,q,Q),w(P,Q,p),w(P,Q,q);return(q>=P)*(Q>=p)if{n,N,m,M}=={0}else(b[1]!=a[0])*(n*N<=0>=m*M)
def f(l):
 i=0
 while i<len(l)-2:
	x=l[i:i+3];i+=1
	if w(*x)==0and s(x)==x:l.pop(i);i-=1
 L=zip(l,l[1:]);return any(I(*l)for l in[(k,x)for i,k in enumerate(L)for x in L[:i]])

Çevrimiçi deneyin!

Algoritmayı buradan , kollear segmentler için bu SO cevabı ile birlikte kullanır .

Düzenleme: (0,0),(1,0),(2,0)Orta noktayı kaldırarak (sonuç olarak (0,0),(2,0)) aynı yönde devam eden çizgi parçaları (örneğin ) için düzeltildi .


İki boşluğun iki örneğinin tümünü tek bir sekmeyle değiştirerek iki bayt kaydedebilirsiniz.
Jonathan Frech

*((n*N>0)+(m*M>0)<1)-> *(n*N<=0>=m*M).
Jonathan Frech

3

Eukleides , 154 148 bayt

number i (set p)
g=card(p);h=g;n=0;e=p[0];q=e.e
for d in p
if h<g-1 
q=q.e
n=card(intersection(d.e,q))>1or d on q?1|n
end
e=d;h=h-1
end;return n;end

Fonksiyon adı iverilen, bir dizi nokta geçti, 0 veya 1 döndürür. Noktalı virgüller ve satır sonları bir komutu sonlandırmak için değiştirilebilir, sadece okunaklı olmadığımız için kodu görünür bir şekilde kısa tutmak için birkaç şeyi bir araya getirdim. Zaten buralarda kod.

Ökleidler, öncelikle grafiksel çıktı için, fakat aynı zamanda iyi programatik yeteneklere sahip bir düzlem geometri dilidir. Bu görev için harika olacağını düşündüm, ama birkaç şey beni hayal kırıklığına uğrattı. Birincisi, Eukleides'teki setlerin esasen nokta dizileri olduğunu ve uygulanabilir olduğunda bağlı çizgi segmentlerinden yapılmış yollar olarak oluşturulduğunu belirtmek gerekir. Eukleides, süreçte bir küme oluşturan bir for-döngüye benzer şekilde lokuslar aracılığıyla yinelemeli kümelerin oluşturulmasını destekler. Bir lokusu kullanabilseydim, baytları tıraş ederdi, ama görünüşe göre Eukleides, kısmen oluşturulmuş bir lokusa kendi içinden referans vermek istemiyor.

Diğer büyük hayal kırıklığı, görünüşte, iki özdeş çizgi parçasının üst üste gelmesi durumunda, intersectionsadece bir kırılma noktası döndürmesi (sanırım, sonsuz kavşaklar olacaktı). Benim yöntemim aslında bir adım gerideki yolu oluşturmak ve bir sonraki çizgi parçasını yolla kesişimler açısından test etmektir. Çünkü yukarıda bahsedilen kesişme davranış noktanın olup olmadığı için ayrı ayrı kontrol ile yol.

Düzenleme : orBir boşluk önce kaldırılmasına izin vermek için deyimi yeniden sıralayarak 1 bayt kesin or; Bu ifbloğu üçlü bir işleme dönüştürerek 5 bayt daha .

Test senaryoları:

ta=point(0,0).point(1,0)
tb=point(0,0).point(1,0).point(0,0)
tc=point(0,0).point(1,0).point(1,1).point(0,0)
td=point(0,0).point(2,0).point(1,1).point(1,-1)
te=point(0,0).point(10,0).point(0,1).point(10,1).point(0,2).point(10,2)
print i(ta);print i(tb);print i(tc);print i(td);print i(te)

0
1
1
1
0
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.