Area del triangolo


16

Un'altra sfida facile per te.

Il tuo compito

Scrivi un programma o una funzione che accetta l'input, che contiene 3 coppie di coordinate x e y e calcola l'area del triangolo formato al loro interno. Per coloro che non ricordano come calcolarlo, puoi trovarlo qui .

Esempio:

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

Guardalo su Wolfram Alpha

Alcune considerazioni:

  • L'input sarà di sei numeri interi positivi di base 10.
  • Si può presumere che l'input sia in qualsiasi formato ragionevole .
  • I punti formeranno sempre un triangolo valido.
  • Si può presumere che l'input sia già memorizzato in una variabile come t.
  • Vince il codice più breve in byte!

Modifica: per evitare qualsiasi confusione, ho semplificato il modo in cui l'input deve essere gestito senza compromettere nessuno dei codici attuali.

Ricorda che il tuo programma / funzione deve generare un'area valida, quindi non può dare un numero negativo come output


1
Ri: la tua modifica. Ciò significa che posso avere un array reale di coppie (ad esempio, [[1, 2], [4, 2], [3, 7]]) in T?
Dennis,

4
Sono ancora confuso. Il post dice ancora sia "3 coppie" che "sei ... numeri interi". Si noti che la rimozione di uno dei due invaliderebbe alcune risposte.
xnor

1
Non mi piace vedere una domanda cambiare dopo aver pubblicato e risposto. Ma questa volta posso salvare altri 2 byte, quindi va bene
edc65

1
Se possiamo prenderli come tre coppie, possiamo prenderli come un array multidimensionale? Cioè, [1 2;4 2;3 7](usando la sintassi di Julia)?
Glen O

2
@YiminRong L'area di un triangolo non può essere negativa per definizione. Non importa in che ordine siano i punti.
Rainbolt

Risposte:


16

CJam, 18 16 byte

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

Provalo online nell'interprete CJam .

Idea

Come accennato su Wikipedia , l'area del triangolo [[0 0] [x y] [z w]]può essere calcolata come |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Per un triangolo generico [[a b] [c d] [e f]], possiamo tradurre il suo primo vertice nell'origine, ottenendo così il triangolo [[0 0] [c-a d-b] [e-a f-b]], la cui area può essere calcolata con la formula sopra.

Codice

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 byte

Area@Polygon@Partition[t,2]

17
Adoro il modo in cui utilizza un built-in ed è ancora più lungo della risposta del cjam.
Carcigenicato,

2
@Carcigenicato il vero problema è il Partition[t,2], che corrisponde al 2/in CJam. ;)
Martin Ender,

10

JavaScript (ES6) 42 .44.

Modifica Il formato di input è cambiato, posso salvare 2 byte

Una funzione anonima che accetta l'array come parametro e restituisce il valore calcolato.

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

Prova a eseguire lo snippet di seguito in un browser compatibile 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
Non potresti semplicemente prendere i valori come parametri standard e salvarti 2 caratteri durante la creazione dell'array?
Mwr247,

@ Mwr247 dice la sfidaThe input will be a vector with six base 10 positive integers.
edc65

Aha. Inizialmente avevo interpretato che come significato ogni coppia costituisce un vettore di coordinate (come nell'esempio di Wolfram), al contrario del fatto che l'input stesso è limitato a un array, e come tale potrebbe usare altri formati. Ha più senso ora.
Mwr247,

@ Mwr247 ora hai ragione
edc65

8

Julia, 32 byte

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

Costruisce una matrice dei termini appropriati di un prodotto incrociato, utilizza detper ottenere il valore risultante, assume un valore assoluto per gestire i negativi e quindi si divide per 2 perché è un triangolo e non un parallelogramma.


7

Matlab / Octave, 26 byte

Non sapevo di questo integrato finora =)

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

6

Java, 79 88 byte

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

Utilizza solo la formula di base, niente di speciale.

Modifica: dimenticato di assumere il valore assoluto :(


non hai bisogno di renderlo eseguibile?
downrep_nation

3
L'esempio mostra solo una chiamata di funzione, e questo è un default relativamente normale qui.
Geobits,

2
In base alla domanda, • Si può presumere che l'input sia già memorizzato in una variabile come 't'. Quindi, return(t[0]*(t[3]...dovrebbe bastare, no?
AdmBorkBork,

@TimmyD Feels ombreggiato farlo, ma sarebbe portarlo giù a 62 byte. Hmmm .... lo lascerò così com'è, almeno per ora.
Geobits,

5

Minkolang 0,8 , 34 byte

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

Qualcuno vuole dell'uovo-n0g ?

Spiegazione

Molto semplice. Usa la formula |(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 byte

Dichiara una funzione anonima:

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

Esempio:

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

cosa fa g?
Level River St

@steveverrill Niente, sono solo un idiota. Riparazione ...
mınxomaτ


3

PHP - 68 88 89 byte

Grazie a Martjin per alcuni ottimi consigli!

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

Per usarlo, crea un file area.phpcon questo contenuto, la riga aggiuntiva incontra il presupposto che i datit vengano salvati in una parte variabile delle specifiche e the alla fine aggiunge un ritorno a capo in modo che l'output sia piacevole e separato:

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

Quindi fornire le coordinate sulla riga di comando come x₁ y₁ x₂ y₂ x₃ y₃, ad es

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

"Puoi presumere che l'input sia già memorizzato in una variabile come t." $a-> $t, rimuove il $a=$argv;salvataggio di 9 byte
Martijn

Successivamente, è possibile sostituire <?php echocon <?=, salvando altri 7 byte
Martijn,

Puoi dire che questo è PHP4.1, con register_globals=Onnel tuo php.inifile (impostazione predefinita). Maggiori informazioni su php.net/manual/en/security.globals.php
Ismael Miguel,


2

R, 37 byte

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

Converte il vettore di coordinate in una matrice e si attacca su una riga di 1.
Calcola il determinante e divide per 2.
Restituisce il risultato assoluto. Se l'ordine fosse sempre in senso orario abs, non sarebbe richiesto.

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

2

Python 2, 48 47 50 byte

Molto semplice; segue l'equazione standard:

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

Gli altri approcci altrettanto semplici sono più lunghi:

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

L'accesso di Python a una determinata funzione è attraverso numpy .

Grazie a muddyfish per 1 byte e xnor per la cattura di un errore.


puoi rimuovere il 0da 2.0partire2.
Blue

Abbastanza vero, @muddyfish, grazie!
Celeo,

Questo è Python 2 o 3? La divisione funziona in modo diverso a seconda della versione ...
mbomb007

Chiarito, @ mbomb007.
Celeo,

1
Hai bisogno di un absper rendere la risposta positiva.
xnor

2

PHP, 77

Sulla base della risposta di @Yimin Rong, ho pensato di poterlo migliorare di qualche byte usando list()piuttosto che direttamente $argvper abbreviare alcune variabili. Inoltre echo, non è necessario uno spazio se c'è delimitatore tra l'eco e la cosa che viene ripetuta.

echo$variable;, echo(4+2);e echo'some string';sono ugualmente validi considerando cheechofunction($variable) confonde PHP.

D'altra parte, ho anche aggiunto abs()di essere matematicamente accurato, poiché alcune combinazioni di vertici hanno prodotto "area negativa"

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

Puoi eseguirlo tramite 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 byte

AWK non ha alcun built-in absquindi usando sqrt(x^2)per sostituire.

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

Salva come area.awke usa come echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, ad es

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

1

PowerShell, 70 byte

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

Utilizza la stessa formula standard di altre soluzioni. Secondo la domanda, si presuppone che l'array sia precompilato, ad es $t=(1,2,4,2,3,7). Ma ooof , la $e la []sintassi uccidono questo ...


Il tuo commento sulla penalità derivante dall'uso $e []mi ha ispirato a provare una soluzione AWK che, per lunghezza, non è competitiva!

1

dc , 52 byte

Presuppone che l'input sia nel registro t come: x1 y1 x2 y2 x3 y3con x1all'inizio dello tstack.

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

Questo utilizza la seguente formula per area:

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

E per una rapida suddivisione del processo:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: imposta la precisione decimale su 1 posizione, sposta le parti della pila nella pila tprincipale e sposta le varie parti della pila principale in altri registri per la memorizzazione ( dduplica la parte superiore della pila principale, rinverte i due elementi superiori della pila principale, L/lsposta / copia dal registro dato al principale,s sposta la parte superiore dello stack principale nel registro indicato)

    Principale: y3 x3 y2 x1

    a:, y1b x2:, c y2:, t:y3

  • la lc lb lt la: Copiare la parte superiore delle pile in registri a, c, b, t, e aalla pila principale in questo ordine

    Principale: y1 y3 x2 y2 y1 y3 x3 y2 x1

    a:, y1b x2:, c y2:, t:y3

  • - * sd: Calcolare ((y3-y1)*x2)e mettere a frutto d(registri a, b, c, et non sono più utilizzati in modo che io farò cadere dalla lista di pile ora)

    Principale: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *: calcolare ((y1-y2)*y3)e ((y2-x3)*x1); conservare il primo ine e lasciare il secondo nella pila principale

    Principale: ((y2-x3)*x1)

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

  • le ld + +: copia la parte superiore del registro ee dnella pila principale, calcola la somma dei primi 2 valori della pila (rimandando il risultato alla pila principale) due volte

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

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

  • 2 /: premi 2 sullo stack principale, dividi i 2 valori nello stack per il 1 ° ( de enon vengono più utilizzati, eliminandoli dall'elenco di stack)

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

Riorganizzando il valore nello stack possiamo vedere che è equivalente alla formula nella parte superiore di questa spiegazione: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: Stampa la parte superiore della pila principale sull'output.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.