ชอบเส้นทางส่วน; สัมผัสเป็นครั้งแรก


14

กำหนดรายการคาร์ทีเซียน 2 จุดหรือมากกว่าที่สั่งให้เอาท์พุทค่าความจริงหากเส้นทางสัมผัสกับตัวเองหรือตัดกันเอง; มิฉะนั้นให้ส่งค่าที่ผิดพลาดหากไม่ได้สัมผัสตัวเองหรือตัดกันเอง

คุณอาจคิดว่าคะแนนต่อเนื่องในรายการนั้นแตกต่างกัน

ตัวอย่าง:

(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

สังเกตพิกัดทั้งหมดที่ฉันให้ที่นี่เป็นจำนวนเต็ม คุณอาจสนับสนุนการป้อนข้อมูลเข้าของสิ่งที่คุณต้องการจาก {จำนวนเต็มทศนิยมทศนิยมเหตุผลลอยตัว ... } แต่การคำนวณการใช้งานของคุณจะต้องให้คำตอบที่ถูกต้องสำหรับอินพุตที่กำหนด


4
สิ่งที่ชื่อดี A +
undergroundmonorail

ฉากแรกของReservoir Dogsทุกคน?
Luis Mendo

ยกโทษให้ฉันถ้าฉันเข้าใจผิด แต่กรณีทดสอบสุดท้ายไม่ตัดกันอย่างไร i.imgur.com/wiNMByd.png
ทั้งหมด

2
@icrieverytim มันไม่ใช่การเดิน จุดสุดท้ายไม่เชื่อมต่อกับจุดแรก
HyperNeutrino

คำตอบ:


5

Python 2 , 315 309 298 382 380 372 ไบต์

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]])

ลองออนไลน์!

ใช้อัลกอริทึมจากที่นี่รวมกับคำตอบ SO นี้สำหรับเซกเมนต์ collinear

แก้ไข: แก้ไขสำหรับส่วนของเส้นตรงที่ดำเนินไปในทิศทางเดียวกัน (เช่น(0,0),(1,0),(2,0)) โดยการลบจุดกึ่งกลาง (ทำให้เกิด(0,0),(2,0))


คุณสามารถบันทึกสองไบต์ด้วยการแทนที่ทั้งสองช่องว่างด้วยแท็บเดียว
Jonathan Frech

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

3

Eukleides , 154 148 bytes

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

ชื่อฟังก์ชั่นiที่ส่งชุดของคะแนนคืน 0 หรือ 1 เซมิโคลอนและตัวแบ่งบรรทัดแทนกันสำหรับการจบคำสั่งฉันเพิ่ง lumped บางสิ่งร่วมกันเพื่อประโยชน์ในการรักษารหัสสั้น ๆ เพราะเราไม่คุ้นเคย รหัสรอบที่นี่ต่อไป

Eukleides เป็นภาษาเรขาคณิตของเครื่องบินเป็นหลักสำหรับการแสดงผลกราฟิก แต่มีความสามารถในการเขียนโปรแกรมที่ดีเช่นกัน ฉันคิดว่ามันจะดีสำหรับงานนี้ แต่มีบางสิ่งที่ทำให้ฉันผิดหวัง ก่อนอื่นมันเป็นเรื่องที่น่าสังเกตว่าชุดใน Eukleides นั้นเป็นอาร์เรย์ของจุดและเมื่อมีการแสดงผลจะเป็นเส้นทางที่ทำจากส่วนของเส้นที่เชื่อมต่อกัน Eukleides สนับสนุนการสร้างชุดวนซ้ำผ่าน loci ซึ่งคล้ายกับ for-loop ที่สร้างชุดในกระบวนการ ถ้าฉันสามารถใช้โลคัสได้มันก็จะถูกลบออกไปเป็นไบต์ แต่เห็นได้ชัดว่า Eukleides ไม่ต้องการอ้างอิงโลคัสที่เกิดขึ้นบางส่วนจากภายในตัวมันเอง

ความไม่พอใจที่สำคัญอื่น ๆ คือถ้าหากดูเหมือนว่าส่วนของเส้นสองส่วนที่เหมือนกันอยู่ด้านบนของกันและกันให้intersectionส่งกลับจุดที่กระทำผิดเพียงจุดเดียวเท่านั้น (ซึ่งฉันรู้สึกว่า วิธีการของฉันเป็นหลักในการสร้างเส้นทางข้างหลังหนึ่งขั้นตอนและทดสอบส่วนของบรรทัดถัดไปสำหรับการแยกกับเส้นทาง เนื่องจากพฤติกรรมการตัดกันที่กล่าวมาข้างต้นฉันตรวจสอบแยกกันว่าจุดนั้นอยู่บนเส้นทางหรือไม่

แก้ไข : ตัด 1 byte โดยจัดเรียงorคำสั่งใหม่เพื่ออนุญาตให้มีการลบช่องว่างก่อนor; 5 ไบต์เพิ่มเติมโดยการเปลี่ยนifบล็อกนั้นเป็นการดำเนินการแบบไตรภาค

กรณีทดสอบ:

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