Área del triángulo


16

Otro desafío fácil para ti.

Tu tarea

Escriba un programa o función que tome la entrada, que contiene 3 pares de coordenadas x e y y calcula el área del triángulo formado dentro de ellos. Para aquellos que no recuerdan cómo calcularlo, lo pueden encontrar aquí .

Ejemplo:

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

Véalo en Wolfram Alpha

Algunas consideraciones

  • La entrada será seis enteros positivos de base 10.
  • Puede suponer que la entrada está en cualquier formato razonable .
  • Los puntos siempre formarán un triángulo válido.
  • Puede suponer que la entrada ya está almacenada en una variable como t .
  • ¡El código más corto en bytes gana!

Editar: para evitar confusiones, he simplificado cómo se debe tratar la entrada sin poner en peligro ninguno de los códigos actuales.

Recuerde que su programa / función debe generar un área válida, por lo que no puede dar un número negativo como salida


1
Re: tu edición. ¿Eso significa que puedo tener una matriz real de pares (por ejemplo, [[1, 2], [4, 2], [3, 7]]) T?
Dennis

44
Todavía estoy confundido. La publicación todavía dice "3 pares" y "seis ... enteros". Tenga en cuenta que eliminar cualquiera de las dos invalidaría algunas respuestas.
xnor

1
No me gusta ver un cambio de pregunta después de publicar y responder. Pero esta vez puedo guardar 2 bytes más, así que está bien
edc65

1
Si podemos tomarlos como tres pares, ¿podemos tomarlos como una matriz multidimensional? Es decir, [1 2;4 2;3 7](usando la sintaxis de Julia)?
Glen O

2
@YiminRong El área de un triángulo no puede ser negativa por definición. No importa en qué orden estén los puntos.
Rainbolt

Respuestas:


16

CJam, 18 16 bytes

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

Pruébelo en línea en el intérprete de CJam .

Idea

Como se menciona en Wikipedia , el área del triángulo [[0 0] [x y] [z w]]se puede calcular como |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Para un triángulo genérico [[a b] [c d] [e f]], podemos traducir su primer vértice al origen, obteniendo así el triángulo[[0 0] [c-a d-b] [e-a f-b]] , cuya área puede calcularse mediante la fórmula anterior.

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

10

Mathematica, 27 bytes

Area@Polygon@Partition[t,2]

17
Me encanta cómo esto usa un incorporado y aún es más largo que la respuesta de cjam.
Carcigenicate

2
@Carcigenicate el verdadero problema es el Partition[t,2], que corresponde al 2/en CJam. ;)
Martin Ender

10

JavaScript (ES6) 42 .44.

Editar el formato de entrada cambiado, puedo guardar 2 bytes

Una función anónima que toma la matriz como parámetro y devuelve el valor calculado.

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

Pruebe a ejecutar el fragmento a continuación en un navegador compatible con 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
¿No podría simplemente tomar los valores como parámetros estándar y ahorrarse 2 caracteres al crear la matriz?
Mwr247

@ Mwr247 dice el desafíoThe input will be a vector with six base 10 positive integers.
edc65

Ajá. Inicialmente había interpretado que significa que cada par forma un vector de coordenadas (como el ejemplo de Wolfram), en lugar de que la entrada en sí se limite a una matriz, y como tal podría usar otros formatos. Tiene más sentido ahora.
Mwr247

@ Mwr247 ahora tienes razón
edc65

8

Julia, 32 bytes

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

Construye una matriz de los términos apropiados de un producto cruzado, usa detpara obtener el valor resultante, toma el valor absoluto para tratar con los negativos y luego divide por 2 porque es un triángulo y no un paralelogramo.


7

Matlab / Octave, 26 bytes

No sabía sobre esto construido hasta ahora =)

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

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

Solo usa la fórmula básica, nada especial.

Editar: Olvidé tomar el valor absoluto :(


no necesitas hacer que sea ejecutable?
downrep_nation

3
El ejemplo solo muestra una llamada de función, y ese es un valor predeterminado relativamente normal aquí.
Geobits

2
Según la pregunta, • Puede suponer que la entrada ya está almacenada en una variable como 't'. Entonces, return(t[0]*(t[3]...debería ser suficiente, ¿no?
AdmBorkBork

@TimmyD Se siente turbio al hacerlo, pero lo reduciría a 62 bytes. Hmmm ... voy a dejarlo como está, al menos por ahora.
Geobits

5

Minkolang 0.8 , 34 bytes

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

¿Alguien quiere un poco de huevo n0g?

Explicación

Muy sencillo Utiliza la 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.

3

JayScript , 58 bytes

Declara una función anónima:

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

Ejemplo:

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

que hace g
Level River St

@steveverrill Nada, solo soy un idiota. Fixing ...
mınxomaτ


3

PHP - 68 88 89 bytes

¡Gracias a Martjin por algunos buenos consejos!

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

Para usarlo, cree un archivo area.phpcon este contenido, la línea adicional cumple con el supuesto de que los datos se guardan en unat parte variable de las especificaciones, y el ␍ al final agrega un retorno de carro para que la salida sea agradable y separada:

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

Luego proporcione las coordenadas en la línea de comando como x₁ y₁ x₂ y₂ x₃ y₃, p. Ej.

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

"Puede suponer que la entrada ya está almacenada en una variable como t". $a-> $t, eliminar $a=$argv;guardar 9 bytes
Martijn

Después de eso, puede reemplazar <?php echocon <?=, guardando otros 7 bytes
Martijn

Puede decir que esto es PHP4.1, con register_globals=Onen su php.iniarchivo (predeterminado). Lea más en php.net/manual/en/security.globals.php
Ismael Miguel


2

R, 37 bytes

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

Convierte el vector de coordenadas en una matriz y las tachuelas en una fila de 1.
Calcula el determinante y divide por 2.
Devuelve el resultado absoluto. Si el pedido fuera siempre en sentido horario abs, no sería necesario.

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

2

Pitón 2, 48 47 50 bytes

Muy simple; sigue la ecuación estándar:

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

Los otros enfoques, igualmente simples, son más largos:

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

El acceso de Python a una función determinada es a través de numpy .

Gracias a muddyfish por 1 byte y xnor por detectar un error.


puede quitar el 0de 2.0a la licencia2.
Azul

Muy cierto, @muddyfish, gracias!
Celeo

¿Es este Python 2 o 3? La división funciona de manera diferente según la versión ...
mbomb007

Aclarado, @ mbomb007.
Celeo

1
Necesita un abspara que la respuesta sea positiva.
xnor

2

PHP, 77

Basado en la respuesta de @Yimin Rong, sentí que podría mejorarlo en unos pocos bytes usando list() lugar de directamente$argv para abreviar algunas variables. tambiénecho necesita un espacio si hay un delimitador entre echo y la cosa que se está haciendo eco.

echo$variable;, echo(4+2); ` yecho'some string'; son igualmente válidos mientras queechofunction($variable) confunde PHP.

Por otro lado, también agregué abs() para ser matemáticamente preciso, ya que algunas combinaciones de vértices produjeron "área negativa"

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

Puedes ejecutarlo a través de 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 bytes

AWK no tiene incorporado, por abslo que usarsqrt(x^2) para sustituir.

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

Guardar como area.awky usar como echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, p. Ej.

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

1

PowerShell, 70 bytes

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

Utiliza la misma fórmula estándar que otras soluciones. Según la pregunta, se supone que la matriz está rellenada previamente, por ejemplo $t=(1,2,4,2,3,7). Pero bueno , ¿la sintaxis $y []mata a este ...


Su comentario sobre la pena de usar $y []me inspiró a tratar una solución AWK, que, por su longitud, no es poco competitivo!

1

corriente continua , 52 bytes

Asume que la entrada está registrada t como: x1 y1 x2 y2 x3 y3con x1en la parte superior de tla pila.

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

Esto usa la siguiente fórmula para el área:

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

Y para un desglose rápido del proceso:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: establezca la precisión decimal en 1 lugar, mueva partes de la pila ta la pila principal y mueva varias partes de la pila principal a otros registros para el almacenamiento ( dduplica la parte superior de la pila principal,r invierte los dos elementos superiores de la pila principal, L/lmueve / copia del registro dado a main,s mueve la parte superior de la pila principal al registro dado)

    Principal: y3 x3 y2 x1

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

  • la lc lb lt la: Copiar la parte superior de las pilas de registros a, c, b, t, ya de la chimenea principal en ese orden

    Principal: y1 y3 x2 y2 y1 y3 x3 y2 x1

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

  • - * sd: Calcular ((y3-y1)*x2)y el resultado puesto en d(registros a, b, c, yt ya no se utilizan de manera voy a soltar desde la lista de las pilas ahora)

    Principal: y2 y1 y3 x3 y2 x1

    re:((y3-y1)*x2)

  • - * se - *: calcular ((y1-y2)*y3)y ((y2-x3)*x1); almacenar el primero ene y dejar el último en la pila principal

    Principal: ((y2-x3)*x1)

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

  • le ld + +: copie la parte superior del registro ey den la pila principal, calcule la suma de los valores de la pila superior 2 (empujando el resultado nuevamente a la pila principal) dos veces

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

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

  • 2 /: empuje 2 en la pila principal, divida los 2dos valores en la pila por la 1ra ( dy eya no se usan, cayéndolos de la lista de pilas)

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

Al reorganizar el valor en la pila, podemos ver que es equivalente a la fórmula en la parte superior de esta explicación: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: Imprime la parte superior de la pila principal para imprimir.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.