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.