Площа трикутника


16

Ще один легкий виклик для вас.

Ваше завдання

Напишіть програму або функцію, яка приймає вхід, який містить 3 пари координат x- і y та обчислює площу трикутника, утвореного всередині них. Для тих, хто не може згадати, як його обчислити, ви можете знайти тут .

Приклад:

1,2,4,2,3,7       # input as x1,y1,x2,y2,x3,y3
7.5               # output

Дивіться це у Wolfram Alpha

Деякі міркування:

  • Вхід складе шість базових 10 натуральних чисел.
  • Ви можете припустити, що дані є у будь-якому розумному форматі .
  • Точки завжди утворюватимуть дійсний трикутник.
  • Ви можете припустити, що вхід вже зберігається в такій змінній, як t.
  • Виграє найкоротший код у байтах!

Редагувати: Щоб уникнути плутанини, я спростив спосіб поводження з входом, не загрожуючи жодному з поточних кодів.

Пам'ятайте, що ваша програма / функція повинна виводити дійсну область, тому вона не може дати негативне число як вихід


1
Re: ваша редакція. Чи означає це, що я можу мати фактичний масив пар (наприклад, [[1, 2], [4, 2], [3, 7]]) у T?
Денніс

4
Я все ще плутаюсь. У публікації все ще написано і "3 пари", і "шість ... цілих чисел". Зауважте, що видалення будь-якої з них призведе до недійсності деяких відповідей.
xnor

1
Мені не подобається змінювати питання після публікації та відповіді. Але цього разу я можу зберегти ще 2 байти, тож все гаразд
edc65

1
Якщо ми можемо прийняти їх як три пари, чи можемо ми прийняти їх як багатовимірний масив? Тобто, [1 2;4 2;3 7](використовуючи синтаксис Юлії)?
Глен О

2
@YiminRong Площа трикутника за визначенням не може бути негативною. Не має значення, в якому порядку розміщуються бали.
Rainbolt

Відповіді:


16

CJam, 18 16 байт

T(f.-~(+.*:-z.5*

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Як згадується у Вікіпедії , площа трикутника [[0 0] [x y] [z w]]може бути обчислена як |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Для родового трикутника [[a b] [c d] [e f]]ми можемо перевести його першу вершину до початку, отримуючи, таким чином, трикутник [[0 0] [c-a d-b] [e-a f-b]], площу якого можна обчислити за вищенаведеною формулою.

Код

T                  e# Push T.
                   e# [[a b] [c d] [e f]]
   (               e# Shift out the first pair.
                   e# [[c d] [e f]] [a b]
    f.-            e# For [c d] and [e f], perform vectorized
                   e# subtraction with [a b].
                   e# [[c-a d-b] [e-a f-b]]
       ~           e# Dump the array on the stack.
                   e# [c-a d-b] [e-a f-b]
        (+         e# Shift and append. Rotates the second array.
                   e# [c-a d-b] [f-b e-a]
          .*       e# Vectorized product.
                   e# [(c-a)(f-b) (d-b)(e-a)]
            :-     e# Reduce by subtraction.
                   e# (c-a)(f-b) - (d-b)(e-a)
              z    e# Apply absolute value.
                   e# |(c-a)(f-b) - (d-b)(e-a)|
               .5* e# Multiply by 0.5.
                   e# |(c-a)(f-b) - (d-b)(e-a)| / 2

10

Математика, 27 байт

Area@Polygon@Partition[t,2]

17
Мені подобається, як для цього використовується Вбудований і все ще довший, ніж відповідь cjam.
Carcigenicate

2
@Carcigenicate справжньою проблемою є те Partition[t,2], що відповідає 2/значенню в CJam. ;)
Мартін Ендер

10

JavaScript (ES6) 42 .44.

Редагувати формат введення змінено, я можу зберегти 2 байти

Анонімна функція, яка приймає масив як параметр і повертає обчислене значення.

(a,b,c,d,e,f)=>(a*(d-f)+c*(f-b)+e*(b-d))/2

Випробуйте запуск фрагмента нижче у веб-переглядачі, сумісному з EcmaScript 6.

f=(a,b,c,d,e,f)=>(a*(d-f)+c*(f-b)+e*(b-d))/2

function test()
{
  var v=I.value.match(/\d+/g)
  I.value = v
  R.innerHTML=f(...v)
}
<input id=I onchange="test()"><button onclick="test()">-></button><span id=R></span>


1
Не могли ви просто взяти значення за стандартні параметри і зберегти собі 2 символи при створенні масиву?
Mwr247

@ Mwr247 виклик говоритьThe input will be a vector with six base 10 positive integers.
edc65

Ага. Я спочатку інтерпретував, що в сенсі кожна пара складає координатний вектор (наприклад, приклад Wolfram), на відміну від того, що сам вхід обмежений масивом, і як такий може використовувати інші формати. Має більше сенсу зараз.
Mwr247

@ Mwr247 зараз ти маєш рацію
edc65

8

Джулія, 32 байти

abs(det(t[1:2].-t[[3 5;4 6]]))/2

Побудує матрицю відповідних доданків перехресного добутку, використовує detдля отримання отриманого значення, приймає абсолютне значення для розгляду негативів, а потім ділиться на 2, оскільки це трикутник, а не паралелограм.


7

Матлаб / Октава, 26 байт

Я не знав про це вбудованому поки що =)

polyarea(t(1:2:5),t(2:2:6))

6

Java, 79 88 байт

float f(int[]a){return Math.abs(a[0]*(a[3]-a[5])+a[2]*(a[5]-a[1])+a[4]*(a[1]-a[3]))/2f;}

Просто використовується основна формула, нічого особливого.

Редагувати: Забули прийняти абсолютне значення :(


вам не потрібно робити його запущеним?
downrep_nation

3
Приклад просто показує виклик функції, і це відносно нормальний стандарт за замовчуванням.
Геобіць

2
За запитання: • Ви можете припустити, що вхід вже зберігається в змінній, наприклад 't'. Отже, return(t[0]*(t[3]...повинно вистачити, ні?
AdmBorkBork

@TimmyD відчуття тіньовим це робити, але це було б довести його до 62 байт. Гмммм .... я збираюся залишити це так, як є, принаймні поки що.
Геобіць

5

Мінколанг 0,8 , 34 байти

ndndn0g-n1g-n0g-n0g-1R*1R*-$~2$:N.

Хтось хоче яєць n0g?

Пояснення

Дуже прямо. Використовує формулу |(x2-x1)(y3-y1) - (x3-x1)(y2-y1)|/2.

nd      x1, x1
nd      x1, x1, y1, y1
n0g-    x1, y1, y1, x2-x1
n1g-    x1, y1, x2-x1, y2-y1
n0g-    y1, x2-x1, y2-y1, x3-x1
n0g-    x2-x1, y2-y1, x3-x1, y3-y1
1R*     y3-y1, x2-x1, (y2-y1)(x3-x1)
1R*     (y2-y1)(x3-x1), (y3-y1)(x2-x1)
-       (y2-y1)(x3-x1) - (y3-y1)(x2-x1)
$~      |(y2-y1)(x3-x1) - (y3-y1)(x2-x1)|
2$:     |(y2-y1)(x3-x1) - (y3-y1)(x2-x1)|/2 (float division)
N.      Output as integer and quit.

3

JayScript , 58 байт

Оголошує анонімну функцію:

function(a,b,c,d,e,f){return (a*(d-f)+c*(f-b)+e*(b-d))/2};

Приклад:

var nFunct = function(a,b,c,d,e,f){return (a*(d-f)+c*(f-b)+e*(b-d))/2};
print(nFunct(1,2,4,2,3,7));

що г робить?
Рівень річки Св.

@steveverrill Нічого, я просто ідіот. Виправлення ...
mınxomaτ


3

PHP - 68 88 89 байт

Дякуємо Мартіну за кілька чудових покажчиків!

<?=.5*abs(($t[1]-$t[5])*($t[4]-$t[2])-($t[1]-$t[3])*($t[6]-$t[2]))?>

Для його використання створіть файл area.phpіз цим вмістом, додатковий рядок відповідає припущенню, що дані зберігаються у зміннійt частині специфікацій, а ␍ в кінці додає повернення каретки, щоб результат був приємним та розділеним:

<?php $t = $argv; ?>
<?=.5*abs(($t[1]-$t[5])*($t[4]-$t[2])-($t[1]-$t[3])*($t[6]-$t[2]))?>
␍

Потім введіть координати в командному рядку як x₁ y₁ x₂ y₂ x₃ y₃, наприклад,

$ php area.php 1 2 4 2 3 7
7.5

"Ви можете припустити, що вхід вже зберігається в такій змінній, як t." $a-> $t, видаліть $a=$argv;збереження 9 байтів
Martijn

Після цього, ви можете замінити <?php echoз <?=, зберігаючи ще 7 байт
Мартейн

Ви можете сказати, що це PHP4.1, register_globals=Onу вашому php.iniфайлі (за замовчуванням). Детальніше читайте на php.net/manual/en/security.globals.php
Ісмаель Мігель


2

R, 37 байт

cat(abs(det(rbind(matrix(t,2),1))/2))

Перетворює вектор координат в матрицю і вказує на рядок 1-х.
Обчислює визначник і ділиться на 2.
Повертає абсолютний результат. Якби замовлення було завжди за годинниковою стрілкою abs, воно не потрібно.

> t = c(1,2,4,2,3,7)
> cat(det(rbind(matrix(t,2),1))/2)
7.5

2

Python 2, 48 47 50 байт

Дуже просто; випливає із стандартного рівняння:

lambda a,b,c,d,e,f:abs(a*(d-f)+c*(f-b)+e*(b-d))/2.

Інші, аналогічно прості підходи довші:

def a(a,b,c,d,e,f):return abs(a*(d-f)+c*(f-b)+e*(b-d))/2. # 57
lambda t:abs(t[0]*(t[3]-t[5])+t[2]*(t[5]-t[1])+t[4]*(t[1]-t[3]))/2. # 67
def a(t):return abs(t[0]*(t[3]-t[5])+t[2]*(t[5]-t[1])+t[4]*(t[1]-t[3]))/2. # 74

Доступ Python до визначеної функції здійснюється через numpy .

Завдяки каламуті за 1 байт та xnor за помилку.


ви можете зняти 0з, 2.0щоб виїхати2.
Синій

Цілком правда, @muddyfish, дякую!
Селео

Це Python 2 чи 3? Відділ працює по-різному в залежності від версії ...
mbomb007

Уточнено @ mbomb007.
Селео

1
Вам потрібно absвідповісти позитивно.
xnor

2

PHP, 77

Виходячи з відповіді @Yimin Rong, я відчув, що міг би покращити його на кілька байтів, використовуючи, list()а не прямо, $argvщоб скоротити деякі змінні. Також echoне потрібен пробіл, якщо між ехо і предметом відлуння є роздільник.

echo$variable;, echo(4+2);і echo'some string';однаково дійсні, тоді як echofunction($variable)плутає PHP.

З іншого боку, я також додав, abs()щоб бути математично точним, оскільки деякі комбінації вершин дали "негативну область"

list($t,$a,$b,$c,$d,$e,$f)=$argv;echo.5*abs(($a-$e)*($d-$b)-($a-$c)*($f-$b));

Ви можете запустити його через CLI

php -r "list($t,$a,$b,$c,$d,$e,$f)=$argv;echo.5*abs(($a-$e)*($d-$b)-($a-$c)*($f-$b));" 1 2 4 2 3 7
7.5

2

AWK - 51 42 байт

AWK не має вбудованого, absтому використовується sqrt(x^2)для підстановки.

{print sqrt((($1-$5)*($4-$2)-($1-$3)*($6-$2))^2)/2}

Збережіть як area.awkі використовуйте як echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, наприклад,

$ echo 1 2 4 2 3 7 | awk -f area.awk
7.5

1

PowerShell, 70 байт

[math]::Abs(($t[0]-$t[4])*($t[3]-$t[1])-($t[0]-$t[2])*($t[5]-$t[1]))/2

Використовується та ж стандартна формула, що й інші рішення. Згідно з питанням, припускаємо, що масив попередньо заповнений, наприклад $t=(1,2,4,2,3,7). Але ooof , робить $і []синтаксис вбити цю ...


Ваш коментар щодо штрафу за використання $та []надихнув мене на спробу рішення AWK, яке, по довжині, не є неконкурентоспроможним!

1

постійного струму , 52 байти

Припускає, що вхід зареєстровано t так: x1 y1 x2 y2 x3 y3з x1у верхній частині tстека.

1kLtLtsaLtsbLtdscLtltrlalclbltla-*sd-*se-*leld++2/p

1 2 4 2 3 7stStStStStSt #puts coordinates into register t (closest thing dc has to variables) 1kLtLtsaLtsbLtdscLtltrlalclbltla-*sd-*se-*leld++2/p 7.5

Для цього використовується наступна формула для області:

(x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

А для швидкого розбиття процесу:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: встановіть десяткову точність на 1 місце, перемістіть частини стека в tосновний стек і перемістіть різні частини основного стека в інші регістри для зберігання ( dдублює верхню частину основного стека, rповерне два верхні елементи основного стека, L/lперемістіть / копія з даного реєстру в основний,s перемістить верхню частину основного стека до заданого реєстру)

    Основні: y3 x3 y2 x1

    a:, y1b:, x2c:, y2t:y3

  • la lc lb lt la: Скопіювати верхню частину штабеля в регістрах a, c, b, t, і aв основний стік в тому порядку ,

    Основні: y1 y3 x2 y2 y1 y3 x3 y2 x1

    a:, y1b:, x2c:, y2t:y3

  • - * sd: Обчислити ((y3-y1)*x2)і покласти результат d(регістри a, b, cі tбільше не використовуються , так що я кину їх зі списку стеків зараз)

    Основні: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *: обчислити ((y1-y2)*y3)і ((y2-x3)*x1); зберігати колишню вe і залишайте останнього на головному стосі

    Основні: ((y2-x3)*x1)

    d:, ((y3-y1)*x2)e:((y1-y2)*y3)

  • le ld + +: скопіюйте верхню частину регістра eта dв основний стек, обчисліть суму значень 2 верхніх стеків (натискання результату назад до основного стеку) двічі

    Основні: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

    d:, ((y3-y1)*x2)e:((y1-y2)*y3)

  • 2 /: натисніть 2 на основний стек, розділіть 2-е значення на стеку на 1-е ( dі eбільше не використовується, викинувши їх зі списку стеків)

    Основні: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

Переставляючи значення на стеку, ми бачимо, що воно рівносильне формулі вгорі цього пояснення: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

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