Giống như một đoạn đường dẫn; xúc động lần đầu tiên


14

Đưa ra một danh sách được sắp xếp từ 2 điểm cartesian 2D trở lên, xuất ra giá trị trung thực nếu đường dẫn tự chạm hoặc tự giao nhau; mặt khác xuất ra một giá trị giả nếu nó không tự chạm vào hoặc tự giao nhau.

Bạn có thể cho rằng các điểm liên tiếp trong danh sách là khác biệt.

Ví dụ:

(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

Lưu ý tất cả các tọa độ tôi đưa ra ở đây là số nguyên. Bạn có thể hỗ trợ các đầu vào phối hợp của bất cứ thứ gì bạn thích ngoài {số nguyên, số thập phân, số hữu tỷ, dấu phẩy động, ...}. Nhưng tính toán triển khai của bạn phải đưa ra câu trả lời chính xác cho bất kỳ đầu vào nào được đưa ra.


4
những gì một tiêu đề tốt A +
undergroundmonorail

Cảnh ban đầu của Reservoir Dogs , có ai không?
Luis Mendo

Hãy tha thứ cho tôi nếu tôi hiểu lầm nhưng trường hợp thử nghiệm cuối cùng không giao nhau như thế nào? i.imgur.com/wiNMByd.png
hoàn toàn là

2
@icrieverytim Đó không phải là một cuộc dạo chơi khép kín. Điểm cuối cùng không kết nối với điểm đầu tiên.
HyperNeutrino

Câu trả lời:


5

Python 2 , 315 309 298 382 380 372 byte

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

Hãy thử trực tuyến!

Sử dụng thuật toán từ đây , kết hợp với câu trả lời SO này cho các phân đoạn cộng tuyến.

Chỉnh sửa: Đã sửa lỗi cho các phân đoạn dòng tiếp tục theo cùng một hướng (ví dụ (0,0),(1,0),(2,0)) bằng cách xóa điểm giữa, (kết quả là (0,0),(2,0)).


Bạn có thể lưu hai byte bằng cách thay thế tất cả hai lần xuất hiện của hai khoảng trắng bằng một tab duy nhất.
Jonathan Frech

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

3

Eukleides , 154 148 byte

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

Hàm được đặt tên iđó, đã vượt qua một tập hợp các điểm, trả về 0 hoặc 1. Dấu chấm phẩy và ngắt dòng có thể hoán đổi cho nhau để kết thúc một lệnh, tôi chỉ gộp một vài thứ lại với nhau để giữ mã rõ ràng vì chúng ta không sử dụng để dễ đọc mã quanh đây nào.

Eukleides là một ngôn ngữ hình học phẳng chủ yếu cho đầu ra đồ họa, nhưng với khả năng lập trình tốt. Tôi nghĩ rằng nó sẽ là tuyệt vời cho nhiệm vụ này, nhưng một vài điều làm tôi thất vọng. Đầu tiên, đáng chú ý là các tập hợp trong Eukleides về cơ bản là các mảng điểm và khi được áp dụng sẽ được hiển thị dưới dạng các đường dẫn được tạo từ các đoạn đường được kết nối. Eukleides hỗ trợ việc tạo các bộ lặp thông qua loci, giống như một vòng lặp for tạo ra một tập hợp trong quy trình. Nếu tôi có thể sử dụng một locus, nó sẽ loại bỏ các byte, nhưng rõ ràng Eukleides không muốn tham chiếu một locus được hình thành một phần từ bên trong chính nó.

Sự thất vọng lớn khác là nếu, dường như, hai đoạn đường giống hệt nhau nằm trên nhau, intersectionchỉ trả về một điểm vi phạm (điều này có nghĩa, tôi cho rằng, sẽ có các giao điểm vô hạn). Phương pháp của tôi về cơ bản là xây dựng đường dẫn một bước phía sau và kiểm tra đoạn đường tiếp theo để biết các giao điểm với đường dẫn. Do hành vi giao cắt đã nói ở trên, tôi kiểm tra riêng xem điểm đó có nằm trên đường dẫn hay không.

Chỉnh sửa : Cắt bỏ 1 byte bằng cách sắp xếp lại orcâu lệnh để cho phép xóa khoảng trắng trước đó or; Thêm 5 byte bằng cách thay đổi ifkhối đó thành một hoạt động ternary.

Các trường hợp thử nghiệm:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.