Яка площа цього багатокутника?


19

Обчисліть площу багатокутника.

Натхненний цим відео алгоритмом шнурівки.

Завдання

Ваше завдання - створити програму або функцію, яка обчислює площу багатокутника. Програма або функція визначається відповідно до визначення за замовчуванням у мета.

Вхідні дані

Ви отримаєте координати X і Y кожної вершини багатокутника. Ви можете взяти дані як список кортежів ( [[x1, y1], [x2, y2], etc]), матриці або плоского списку ( [x1, y1, x2, y2, etc]). Дозволено також два списки, що містять xі yкоординати відповідно. Вершини нумеруються проти годинникової стрілки, і перша вершина така ж, як і остання надана вершина, таким чином закриваючи багатокутник.

Якщо ви хочете, ви можете взяти дані без останньої вершини (тому отримайте кожну координату лише один раз).

Можна припустити, що краї многокутників не перетинаються. Можна також припустити, що всі вершини мають цілі координати.

Вихідні дані

Площа багатокутника. Дозволені всі стандартні методи виведення. Якщо у вашій мові не передбачено поділу на поплавці і рішення не було б цілим числом, ви можете повернути дріб. Фракцію не обов’язково спрощувати, тому повертаючись2/4 було б дозволеним.

Критерій виграшу

Найкоротший код виграє!

Тестові справи

[[4,4],[0,1],[-2,5],[-6,0],[-1,-4],[5,-2],[4,4]]
55

введіть тут опис зображення

[[1,1],[0,1],[1,0],[1,1]]
0.5
1/2

введіть тут опис зображення


Чи [x1, x2, x3], [y1, y2, y3]дозволено введення ?
програміст5000

@ programmer5000 та Мартін Ендер, так, я це відредагую :)
JAD

Я згоден, проголосував за повторне відкриття.
програміст5000

1
@flawr Я зробив, що це обман. Насправді це не дупа своєї мети, яка застосовувати той же метод, що і тут рекурсивно, вимагатиме пошуку вершин, які є пунктами перетину, і вимагатиме впорядкування отриманих підмножин у спосіб проти годинникової стрілки - це здається набагато складнішим.
Джонатан Аллан

Відповіді:


13

Желе ,  8  6 байт

-1 байт завдяки Emigna (надлишковий , ÆḊмає ліву глибину 2)
-1 байт завдяки Emigna, знову ж таки (половина,, Hплаваюча точка не потребує ÷2)

ṡ2ÆḊSH

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

Спробуйте в Інтернеті!

Як?

Застосовує алгоритм шнурівки, як описано у відео (яке я теж переглядав днями!)

ṡ2ÆḊSH - Link: list of [x,y] coordinate pairs anticlockwise & wrapped, p
ṡ2     - all overlapping slices of length 2
  ÆḊ   - determinant (vectorises)
    S  - sum
     H - halve

Другий тестовий випадок повертає для мене `-0,5`: o
JAD

О, мені доведеться це перевірити ...
Джонатан Аллан

Це тому, що як [x,y]координати вони задаються за годинниковою стрілкою, а не проти годинникової стрілки. Вхід [[1,1],[0,1],[1,0],[1,1]]буде повертати a 0.5.
Джонатан Аллан

1
Woops, я відредагую це: D
JAD

1
Також Hзамість÷2
Emigna



16

JavaScript (ES6), 69 67 47 байт

Завдяки @Rick за те, що помітив, що нам не потрібне абсолютне значення, якщо вершини гарантовано будуть відсортовані у порядку проти годинникової стрілки та запропонували взяти плоский список як вхід, заощадивши 20 байт!

Вводиться в якості плоского списку вершин, включаючи останню вершину.

f=([x,y,...a])=>1/a[0]?x*a[1]/2-y*a[0]/2+f(a):0

Спробуйте в Інтернеті!

Як?

н

аrеа=|(х0у1-у0х1)+(х1у2-у1х2)++(хн-1у0-ун-1х0)2|


Дуже вражає! Чи можете ви пояснити, як це працює?
Ругнір

Вершини у другому тестовому випадку були помилково впорядковані. Абс не повинен бути необхідним.
Рік

Ви також можете зберегти 7 байт, перейшовши на плоский список:a=>(g=([x,y,...a])=>1-a?0:x*a[1]-y*a[0]+g(a))(a)/2
Rick

@Rick має рацію - абс не потрібно. Без нього формула обчислює підписану площу, що є позитивним, оскільки вершини задаються в порядку проти годинникової стрілки.
Ангс

@Rick Дякую! Оновлено ... приблизно через 10 місяців: /
Арнольд

7

R, 54 52 байти

pryr::f({for(i in 2:nrow(x))F=F+det(x[i-1:0,]);F/2})

Який оцінює функцію:

function (x) 
{
    for (i in 2:nrow(x)) F = F + det(x[i - 1:0, ])
    F/2
}

Використовує попередньо визначене F = FALSE = 0. Реалізує алгоритм шнурівки у зв'язаному відео :)

-2 байти завдяки Джузеппе


-1 байт i+-1:0як індекс рядка
Джузеппе

@Giuseppe Nice. Я зніму +також;)
JAD

6

Python 3 , 72 71 байт

from numpy import*
g=lambda x,y:(dot(x[:-1],y[1:])-dot(x[1:],y[:-1]))/2

Бере два списки, як це було дозволено в коментарях

x = [x0,x1,x2, ...]
y = [y0,y1,y2, ...] 

Спробуйте в Інтернеті!

Це в основному лише реалізація формули шнурок . Чи можу я отримати додаткові бали за гольф, який ви насправді реалізували б так? : D

-1, позаду немає місця x,y:.



Узяття двох списків також згадується в тілі питання зараз :)
JAD

@JarkoDubbeldam Гм, я щойно бачив, що він повинен виводити область. Наразі це рішення просто повертає область. Це також дозволено, або це буде надруковано?
P. Siehr

Функція, що повертає значення, зараховується як вихід :)
JAD

Я думаю, що з python вам навіть не потрібно називати функцію, тому просто починати з lambda x,y:цього добре.
JAD

@JarkoDubbeldam Чи є правила для кожної мови?
P. Siehr


4

JS (ES6), 98 95 94 93 88 86 82 81 77 73 байт

(X,Y)=>{for(i in X){a+=(X[i]+X[i-1])*(Y[i]-Y[i-1]);if(!+i)a=0}return a/2}

Приймає вхід як [x1, x2, x3], [y1, y2, y3]і пропускає повторну пару координат.

-3 байти завдяки @JarkoDubbeldam

-4 байти завдяки @JarkoDubbeldam

-1 байт завдяки @ZacharyT

-4 байти завдяки @ZacharyT

-4 байти завдяки @Rick


3

J, 12 байт

Припустимо, що вхід - це список із двох списків елементів (тобто таблиця)

-:+/-/ .*2[\
  • 2[\ - розбиває його на шнурок Xs, тобто перекриваючи квадрати 4 в’язи
  • -/ .* - визначник кожного
  • +/ - підсумуйте
  • -: - ділимо на 2

Якщо ми отримуємо введення як єдиний список, нам потрібно спершу перетворитись на таблицю, давши нам 20 байт:

-:+/-/ .*2[\ _2&(,\)

1
"Припустимо, що введення - це список із двох списків елементів (тобто таблиця)" Це дозволено :)
JAD

3

MS-SQL, 66 байт

SELECT geometry::STPolyFromText('POLYGON('+p+')',0).STArea()FROM g

MS SQL 2008 і вище підтримують відкритий геопросторовий консорціум (OGC) -стандартних просторових даних / функцій, якими я тут користуюся.

Вхідні дані зберігаються у полі p попередньо існуючої таблиці g , в відповідно з нашими стандартами введення .

Введення - це текстове поле з упорядкованими парами у такому форматі: (4 4,0 1,-2 5,-6 0,-1 -4,5 -2,4 4)

Тепер просто заради задоволення, якщо ви дозволили моїй таблиці введення містити стандартні об’єкти геометрії "Відкритий геопросторовий консорціум" (замість просто текстових даних), то вона стає майже тривіальною:

--Create and populate input table, not counted in byte total
CREATE TABLE g (p geometry)
INSERT g VALUES (geometry::STPolyFromText('POLYGON((5 5, 10 5, 10 10, 5 5))', 0))

--23 bytes!
SELECT p.STArea()FROM g


0

Perl 5 -pa , 62 байти

map$\+=$F[$i]*($a[($i+1)%@a]-$a[$i++-1]),@a=eval<>}{$\=abs$\/2

Спробуйте в Інтернеті!

Приймає введення як список координат X у першому рядку з подальшим переліком координат Y у другому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.