Як шлях-відрізок; торкнувся вперше


14

Враховуючи впорядкований список з 2 або більше 2D декартових точок, виведіть триєдине значення, якщо або шлях торкається себе, або самоперетинається; інакше виведіть помилкове значення, якщо воно не торкається себе або самоперетинається.

Ви можете припустити, що послідовні пункти у списку відрізняються.

Приклади:

(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 +
підземний


Пробачте, якщо я нерозумію, але як останній тестовий випадок не перетинається? 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 відповідь на колінеарних сегментів.

Редагувати: виправлено для сегментів рядка, що продовжуються в тому ж напрямку (наприклад (0,0),(1,0),(2,0)), видаливши середню точку (в результаті (0,0),(2,0)).


Ви можете зберегти два байти, замінивши всі два входження двох пробілів однією вкладкою.
Джонатан Фрех

*((n*N>0)+(m*M>0)<1)-> *(n*N<=0>=m*M).
Джонатан Фрех

3

Еклеїди , 154 148 байт

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. Точки з комою та розривами рядків є взаємозамінними для закінчення команди, я просто зібрав кілька речей разом, щоб код був помітно коротким, оскільки ми не звикли читати код тут все одно.

Еклеїди - це плоска мова геометрії головним чином для графічного виведення, але також з гідними програмними здібностями. Я думав, що це буде чудово для цього завдання, але кілька речей мене засмутили. По-перше, варто відзначити, що множини в Eukleides - це по суті масиви точок, і коли це застосовано, виводяться у вигляді контурів, виконаних із з’єднаних відрізків ліній. Eukleides підтримує ітераційне генерування наборів за допомогою локусів, схожих на цикл for, який створює набір у процесі. Якби я міг використати локус, він би відголив байти, але, мабуть, Еклеїди не люблять посилатися на частково сформований локус всередині себе.

Інша велика розчарування полягала в тому, що якщо, здавалося б, два однакових відрізка ліній розташовуються один над одним, intersectionповертається лише одна точка образи (що, мабуть, має сенс, було б нескінченне перехрестя). Мій метод полягає в тому, щоб побудувати шлях на один крок позаду і протестувати наступний відрізок рядка на перетини шляху. Через вищезгадану поведінку перехрестя я окремо перевіряю, чи є точка на шляху.

Редагувати : відріжте 1 байт, упорядкувавши 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.