Área do triângulo

16

Outro desafio fácil para você.

Sua tarefa

Escreva um programa ou função que aceite a entrada, que contenha 3 pares de coordenadas xe y e calcule a área do triângulo formado dentro delas. Para aqueles que não conseguem se lembrar de como calculá-lo, você pode encontrá-lo aqui .

Exemplo:

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

Veja no Wolfram Alpha

Algumas considerações:

  • A entrada será de seis números inteiros positivos da base 10.
  • Você pode assumir que a entrada está em qualquer formato razoável .
  • Os pontos sempre formarão um triângulo válido.
  • Você pode assumir que a entrada já está armazenada em uma variável como t.
  • O código mais curto em bytes vence!

Edit: Para evitar qualquer confusão, simplifiquei como a entrada deve ser tratada sem comprometer nenhum dos códigos atuais.

Lembre-se de que o seu programa / função deve gerar uma área válida, portanto não pode dar um número negativo como saída

Mutador
fonte
11
Re: sua edição. Isso significa que eu posso ter uma matriz real de pares (por exemplo [[1, 2], [4, 2], [3, 7]]) T?
Dennis
4
Eu ainda estou confuso. O post ainda diz "3 pares" e "seis ... números inteiros". Observe que a remoção de qualquer um deles invalidaria algumas respostas.
Xnor
11
Não gosto de ver uma pergunta mudar depois de postar e responder. Mas desta vez eu possa salvar mais 2 bytes, então está tudo certo
edc65
11
Se pudermos aceitá-los como três pares, podemos aceitá-los como uma matriz multidimensional? Ou seja, [1 2;4 2;3 7](usando a sintaxe de Julia)?
Glen O
2
@YiminRong A área de um triângulo não pode ser negativa por definição. Não importa em que ordem estão os pontos.
Rainbolt 15/10/2015

Respostas:

16

CJam, 18 16 bytes

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

Experimente online no intérprete CJam .

Idéia

Como mencionado na Wikipedia , a área do triângulo [[0 0] [x y] [z w]]pode ser calculada como |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Para um triângulo genérico [[a b] [c d] [e f]], podemos traduzir seu primeiro vértice para a origem, obtendo assim o triângulo [[0 0] [c-a d-b] [e-a f-b]], cuja área pode ser calculada pela fórmula acima.

Código

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
Dennis
fonte
10

Mathematica, 27 bytes

Area@Polygon@Partition[t,2]
alefalpha
fonte
17
Eu amo como isso usa um Built-in e ainda é mais longo que a resposta cjam.
Carcigenicate
2
@Carcigenicate o problema real é o Partition[t,2], que corresponde ao 2/CJam. ;)
Martin Ender
10

JavaScript (ES6) 42 .44.

Editar Formato de entrada alterado, posso salvar 2 bytes

Uma função anônima que toma a matriz como parâmetro e retorna o valor calculado.

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

Teste a execução do snippet abaixo em um navegador compatível com 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>

edc65
fonte
11
Você não poderia simplesmente pegar os valores como parâmetros padrão e economizar 2 caracteres ao criar a matriz?
Mwr247
@ Mwr247 o desafio dizThe input will be a vector with six base 10 positive integers.
edc65
Aha. Inicialmente, interpretei que, como significando que cada par compõe um vetor de coordenadas (como o exemplo Wolfram), em oposição à entrada em si limitada a uma matriz e, como tal, poderia usar outros formatos. Faz mais sentido agora.
Mwr247
@ Mwr247 now you right
edc65
8

Julia, 32 bytes

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

Constrói uma matriz dos termos apropriados de um produto cruzado, usa detpara obter o valor resultante, assume valor absoluto para lidar com negativos e depois divide por 2 porque é um triângulo e não um paralelogramo.

Glen O
fonte
7

Matlab / Octave, 26 bytes

Eu não sabia sobre isso construído até agora =)

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

Java, 79 88 bytes

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;}

Apenas usa a fórmula básica, nada de especial.

Edit: Esqueceu de levar o valor absoluto :(

Geobits
fonte
você não precisa torná-lo executável?
downrep_nation
3
O exemplo mostra apenas uma chamada de função, e esse é um padrão relativamente normal aqui.
Geobits 14/10
2
De acordo com a pergunta, • Você pode assumir que a entrada já está armazenada em uma variável como 't'. Então, return(t[0]*(t[3]...deveria bastar, não?
AdmBorkBork 14/10
@ TimmyD Parece obscuro fazê-lo, mas reduziria para 62 bytes. Hummm .... vou deixar como está, por enquanto, pelo menos por enquanto.
Geobits
5

Tamanho 0.8 , 34 bytes

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

Alguém quer ovo n0g?

Explicação

Muito simples. Usa a fórmula |(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.
El'endia Starman
fonte
3

JayScript , 58 bytes

Declara uma função anônima:

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

Exemplo:

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));
mınxomaτ
fonte
o que g faz?
Level River St
@steveverrill Nada, eu sou apenas um idiota. Corrigindo ...
mınxomaτ 14/10/2015
3

Ruby, 45

->a,b,p,q,x,y{((a-x)*(q-y)-(p-x)*(b-y)).abs/2}
Level River St
fonte
3

PHP - 68 88 89 bytes

Obrigado a Martjin por ótimas dicas!

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

Para usá-lo, crie um arquivo area.phpcom esse conteúdo, a linha extra atende ao pressuposto de que os dados são salvos em umat parte variável das especificações e o ␍ no final adiciona um retorno de carro para que a saída seja agradável e separada:

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

Em seguida, forneça as coordenadas na linha de comando como x₁ y₁ x₂ y₂ x₃ y₃, por exemplo,

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

fonte
"Você pode assumir que a entrada já está armazenada em uma variável como t." $a-> $t, remova $a=$argv;salvar 9 bytes
Martijn
Depois disso, você pode substituir <?php echopor <?=, salvando outros 7 bytes
Martijn
Você pode dizer que isso é PHP4.1, com register_globals=Onno seu php.iniarquivo (padrão). Leia mais em php.net/manual/en/security.globals.php
Ismael Miguel
2

Pitão, 34 30 bytes

KCcQ2c.asm*@hKd-@eKhd@eKtdU3 2

Experimente online.

Funciona calculando abs (a * (df) + c * (fb) + e * (bd)) / 2 a partir da entrada a, b, c, d, e, f.

Sam Cappleman-Lynes
fonte
2

R, 37 bytes

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

Converte o vetor de coordenadas em uma matriz e aderência em uma linha de 1's.
Calcula o determinante e divide por 2.
Retorna o resultado absoluto. Se o pedido fosse sempre no sentido horário, absisso não seria necessário.

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

Python 2, 48 47 50 bytes

Muito simples; segue a equação padrão:

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

As outras abordagens igualmente simples são mais longas:

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

O acesso do Python a uma função determinada é através de numpy .

Graças a muddyfish para 1 byte e xnor para a captura de um erro.

Celeo
fonte
você pode remover a 0partir de 2.0para sair #2.
Blue
É verdade, @muddyfish, obrigado!
Celeo # 14/15
Este é o Python 2 ou 3? Obras de divisão de forma diferente dependendo da versão ...
mbomb007
Esclarecido, @ mbomb007.
Celeo
11
Você precisa de um abspara tornar a resposta positiva.
Xnor
2

PHP, 77

Com base na resposta de @Yimin Rong, senti que poderia melhorar alguns bytes usando, list()ao invés de direto, $argvabreviar algumas variáveis. Além dissoecho não precisa de um espaço se houver delimitador entre eco e a coisa que está sendo ecoada.

echo$variable;, echo(4+2);e echo'some string';são igualmente válidos enquantoechofunction($variable) confunde PHP.

Por outro lado, também adicionei abs()ser matematicamente preciso, pois algumas combinações de vértices geravam "área negativa"

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

Você pode executá-lo via 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
JPMC
fonte
2

AWK - 51 42 bytes

O AWK não possui built-in, absportanto, use-o sqrt(x^2)para substituir.

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

Salvar como area.awke usar como echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, por exemplo

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

fonte
1

PowerShell, 70 bytes

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

Usa a mesma fórmula padrão que outras soluções. De acordo com a pergunta, assume que a matriz é pré-preenchida, por exemplo $t=(1,2,4,2,3,7). Mas ooof , a sintaxe $e []mata este ...

AdmBorkBork
fonte
Seu comentário sobre a penalidade de usar $e []me inspirou a tentar uma solução AWK que, por extensão, não é competitiva!
1

dc , 52 bytes

Assume que a entrada está registrada t como: x1 y1 x2 y2 x3 y3with x1no topo da tpilha.

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

Isso usa a seguinte fórmula para a área:

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

E para uma rápida análise do processo:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: defina a precisão decimal como 1 local, mova partes da pilha tpara a pilha principal e mova várias partes da pilha principal para outros registradores para armazenamento ( dduplica o topo da pilha principal, rinverte os dois principais elementos da pilha principal, L/lmova / copiar do registro fornecido para main,s move o topo da pilha principal para o registro fornecido)

    A Principal: y3 x3 y2 x1

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

  • la lc lb lt la: Copiar o topo das pilhas em registos a, c, b, t, e apara a pilha principal nessa ordem

    A Principal: y1 y3 x2 y2 y1 y3 x3 y2 x1

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

  • - * sd: Calcular ((y3-y1)*x2)eo resultado colocar em d(registros a, b, c, et não são mais usados por isso vou deixá-los na lista de pilhas agora)

    A Principal: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *: computação ((y1-y2)*y3)e ((y2-x3)*x1); armazenar o primeiro eme e deixe o último na pilha principal

    A Principal: ((y2-x3)*x1)

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

  • le ld + +: copie o topo do registro ee dpara a pilha principal, calcule a soma dos 2 principais valores da pilha (retornando o resultado para a pilha principal) duas vezes

    A Principal: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

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

  • 2 /: pressione 2 na pilha principal, divida o 2º valor na pilha pelo 1º ( de enão são mais usados, removendo-os da lista de pilhas)

    A Principal: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

Reorganizando o valor na pilha, podemos ver que é equivalente à fórmula na parte superior desta explicação: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: Imprima a parte superior da pilha principal para a saída.
SnoringFrog
fonte