Визначте, чи багатокутник опуклий


21

Напишіть програму, щоб визначити, чи введений багатокутник випуклий . Багатокутник задається однією лінією, що містить N , кількість вершин, потім N рядків, що містять координати x і y кожної вершини. Вершини будуть перераховані за годинниковою стрілкою, починаючи з довільної вершини.

приклад 1

вхід

4
0 0
0 1
1 1
1 0

вихід

convex

приклад 2

вхід

4
0 0
2 1
1 0
2 -1

вихід

concave

приклад 3

вхід

8
0 0
0 1
0 2
1 2
2 2
2 1
2 0
1 0

вихід

convex

x і y - цілі числа, N <1000 , і | x |, | y | <1000 . Ви можете припустити, що вхідний многокутник простий (жоден з ребер не перетинається, лише 2 ребра торкаються кожної вершини). Найкоротша програма виграє.


"Простий" не включає "послідовні ребра неколінеарні" ?! Також ще кілька тестів: (0,0) (0,2) (2,2) (2,0) (1,1); та (1,1) (0,0) (0,2) (2,2) (2,0) - для перевірки випадків, коли знаходження увігнутої вершини вимагає обгортання від кінця назад до початку.
Пітер Тейлор

Це питання старіє, але ... Розглянемо додавання увігнутого прикладу з двома вирівняними сегментами, наприклад, модифікацією прикладу 2: (0,0), (2,1), (4,2), (1,0) ( 2, -1). Я підводжу це, тому що я роздував приклад 3, не усвідомлюючи цього.
Джессі Мілікан

Відповіді:


4

J, 105

echo>('concave';'convex'){~1=#=(o.1)([:>-.~)(o.2)|3([:-/12 o.-@-/@}.,-/@}:)\(,2&{.)j./"1}.0&".;._2(1!:1)3

Проходить усі три випробування вище.

Редагувати: (111-> 115) Обробляйте однолінійні точки, усуваючи кути pi. Набрав декількох персонажів в іншому місці.

Редагувати: (115-> 105) Менш німий.

Пояснення для людей з обмеженими можливостями J:

  • (1!:1)3читати STDIN до EOF. (Я думаю.)
  • 0&".;._2 це приємна ідіома для розбору такого роду даних.
  • j./"1}. відключіть перший рядок введення (N 0) і перетворіть пари в комплекси.
  • (,2&{.) позначте перші два пункти в кінці списку.
  • 3(f)\ застосовується f до розсувного вікна довжиною 3 (3 бали за кут)
  • [:-/12 o.-@-/@}.,-/@}: - дієслово, яке перетворює кожну 3 точку на кут між -pi та pi.
    • -@-/@}.,-/@}:виробляє (p1 - p2), (p3 - p2). (Нагадаємо, що це комплекси.)
    • 12 o. дає кут для кожного комплексу.
    • [:-/(...) дає різницю двох кутів.
  • (o.1)([:>-.~)(o.2)| mod 2 pi, усуньте кути pi (прямі відрізки) та порівняйте з pi (більший, менший, не має значення, якщо точки не повинні бути намотані в одну сторону).
  • 1=#= якщо всі результати порівняння 1 або 0 (із самокласифікацією. Це здається німим).
  • echo>('concave';'convex'){~ друк опуклий.

3

Пітон - 149 символів

p=[map(int,raw_input().split())for i in[0]*input()]*2
print'ccoonncvaevxe'[all((a-c)*(d-f)<=(b-d)*(c-e)for(a,b),(c,d),(e,f)in zip(p,p[1:],p[2:]))::2]

Я думаю, що вам потрібно <=, див. Приклад 3 Я щойно додав.
Кіт Рендалл

1
чорт, цей шматочок ...
st0le

2

Рубі 1,9, 147 133 130 124 123

gets
puts ($<.map{|s|s.split.map &:to_i}*2).each_cons(3).any?{|(a,b),(c,d),(e,f)|(e-c)*(d-b)<(d-f)*(a-c)}?:concave: :convex

1

шкала: 297 символів

object C{class D(val x:Int,val y:Int)
def k(a:D,b:D,c:D)=(b.y-a.y)*(c.x-b.x)>=(c.y-b.y)*(b.x-a.x) 
def main(a:Array[String]){val s=new java.util.Scanner(System.in)
def n=s.nextInt
val d=for(x<-1 to n)yield{new D(n,n)}print((true/:(d:+d.head).sliding(3,1).toList)((b,t)=>b&&k(t(0),t(1),t(2))))}}

1
Ви можете поголити три символи, використовуючи def main(a:...замість них def main(args:....
Гарет

Так, я помітив себе, але 299–149 не приносить мене в область когось іншого. Можливо, якщо я знайду інші вдосконалення - ах, є одне: n - ім'я функції (наступне) та ім'я змінної.
користувач невідомий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.