Fläche des Dreiecks

16

Eine weitere leichte Herausforderung für Sie.

Deine Aufgabe

Schreiben Sie ein Programm oder eine Funktion, die die Eingabe übernimmt, die drei Paare von x- und y-Koordinaten enthält und die Fläche des darin gebildeten Dreiecks berechnet. Für diejenigen, die sich nicht erinnern können, wie man es berechnet, finden Sie es hier .

Beispiel:

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

Sehen Sie es bei Wolfram Alpha

Einige Überlegungen:

  • Die Eingabe besteht aus sechs positiven Ganzzahlen zur Basis 10.
  • Sie können davon ausgehen, dass die Eingabe in einem angemessenen Format vorliegt .
  • Die Punkte bilden immer ein gültiges Dreieck.
  • Sie können davon ausgehen, dass die Eingabe bereits in einer Variablen wie gespeichert ist t.
  • Der kürzeste Code in Bytes gewinnt!

Bearbeiten: Um Verwirrung zu vermeiden, habe ich vereinfacht, wie die Eingabe behandelt werden soll, ohne einen der aktuellen Codes zu gefährden.

Denken Sie daran, dass Ihr Programm / Ihre Funktion einen gültigen Bereich ausgeben muss, damit keine negative Zahl ausgegeben werden kann

Mutador
quelle
1
Betreff: Deine Bearbeitung. Bedeutet das, dass ich ein tatsächliches Array von Paaren (zB [[1, 2], [4, 2], [3, 7]]) in haben kann T?
Dennis
4
Ich bin immer noch verwirrt. Der Post sagt immer noch "3 Paare" und "sechs ... ganze Zahlen". Beachten Sie, dass das Entfernen einer der beiden Antworten einige ungültig machen würde.
Xnor
1
Ich mag es nicht, wenn sich eine Frage nach dem Posten und Beantworten ändert. Aber dieses Mal kann ich 2 weitere Bytes sparen, also ist es in Ordnung
edc65
1
Wenn wir sie in drei Paaren aufnehmen können, können wir sie dann als mehrdimensionales Array aufnehmen? Das heißt [1 2;4 2;3 7](mit Julia-Syntax)?
Glen O
2
@YiminRong Die Fläche eines Dreiecks kann per Definition nicht negativ sein. Es spielt keine Rolle, in welcher Reihenfolge sich die Punkte befinden.
Rainbolt

Antworten:

16

CJam, 18 16 Bytes

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

Probieren Sie es online im CJam-Interpreter aus .

Idee

Wie auf Wikipedia erwähnt , kann die Fläche des Dreiecks [[0 0] [x y] [z w]]wie folgt berechnet werden |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Für ein generisches Dreieck [[a b] [c d] [e f]]können wir seinen ersten Scheitelpunkt in den Ursprung übersetzen und so das Dreieck erhalten [[0 0] [c-a d-b] [e-a f-b]], dessen Fläche mit der obigen Formel berechnet werden kann.

Code

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
quelle
10

Mathematica, 27 Bytes

Area@Polygon@Partition[t,2]
Alephalpha
quelle
17
Ich liebe es, wie dies ein Built-in nutzt und immer noch länger ist als die cjam-Antwort.
Carcigenicate
2
@Carcigenicate das eigentliche Problem ist das Partition[t,2], was dem 2/in CJam entspricht. ;)
Martin Ender
10

JavaScript (ES6) 42.44.

Bearbeiten Eingabeformat geändert wird , kann ich 2 Bytes speichern

Eine anonyme Funktion, die das Array als Parameter verwendet und den berechneten Wert zurückgibt.

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

Testen Sie das folgende Snippet in einem EcmaScript 6-kompatiblen Browser.

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
quelle
1
Könnten Sie nicht einfach die Werte als Standardparameter verwenden und sich beim Erstellen des Arrays 2 Zeichen sparen?
Mwr247
@ Mwr247 die Herausforderung sagtThe input will be a vector with six base 10 positive integers.
edc65
Aha. Anfangs hatte ich das so interpretiert, dass jedes Paar einen Koordinatenvektor bildet (wie das Wolfram-Beispiel), im Gegensatz dazu, dass die Eingabe selbst auf ein Array beschränkt ist und als solche andere Formate verwenden könnte. Macht jetzt mehr Sinn.
Mwr247
@ Mwr247 jetzt hast du recht
edc65
8

Julia, 32 Bytes

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

Erstellt eine Matrix mit den entsprechenden Begriffen eines Kreuzprodukts, ermittelt detdaraus den resultierenden Wert, nimmt den absoluten Wert für den Umgang mit Negativen und dividiert ihn dann durch 2, da es sich um ein Dreieck und nicht um ein Parallelogramm handelt.

Glen O
quelle
7

Matlab / Octave, 26 Bytes

Ich wusste bisher nichts davon eingebaut =)

polyarea(t(1:2:5),t(2:2:6))
fehlerhaft
quelle
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;}

Verwendet nur die Grundformel, nichts Besonderes.

Edit: Vergaß den absoluten Wert zu nehmen :(

Geobits
quelle
Müssen Sie es nicht lauffähig machen?
Downrep_nation
3
Das Beispiel zeigt nur einen Funktionsaufruf, und das ist hier eine relativ normale Standardeinstellung.
Geobits
2
Zu der Frage: • Sie können davon ausgehen, dass die Eingabe bereits in einer Variablen wie 't' gespeichert ist. Also return(t[0]*(t[3]...sollte es genügen, nein?
AdmBorkBork
@TimmyD Fühlt sich zwielichtig an, würde es aber auf 62 Bytes reduzieren . Hmmm ... ich werde es so lassen, wie es ist, zumindest für den Moment .
Geobits
5

Minkolang 0,8 , 34 Bytes

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

Wer will etwas Ein0g ?

Erläuterung

Sehr einfach. Verwendet die Formel |(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
quelle
3

JayScript , 58 Bytes

Deklariert eine anonyme Funktion:

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

Beispiel:

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τ
quelle
was macht g
Level River St
@ Steveverrill Nichts, ich bin nur ein Idiot. Fixing ...
Mittwoch,
3

Rubin, 45

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

PHP - 68 88 89 Bytes

Vielen Dank an Martjin für ein paar tolle Hinweise!

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

Um es zu verwenden, erstellen Sie eine Datei area.phpmit diesem Inhalt, die zusätzliche Zeile entspricht der Annahme, dass die Daten in einem variablent Teil der Spezifikation gespeichert sind , und das ␍ am Ende fügt einen Wagenrücklauf hinzu, damit die Ausgabe schön und getrennt ist:

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

Geben Sie dann die Koordinaten in der Befehlszeile ein x₁ y₁ x₂ y₂ x₃ y₃, z

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

quelle
Msgstr "Sie können davon ausgehen, dass die Eingabe bereits in einer Variablen wie gespeichert ist t." $a-> $t, entfernen Sie $a=$argv;9 Bytes speichern
Martijn
Danach können Sie ersetzen <?php echomit <?=, weitere 7 Bytes Speicher
Martijn
Sie können sagen, dass dies PHP4.1 ist, mit register_globals=Onin Ihrer php.iniDatei (Standard). Weitere Informationen finden
Ismael Miguel
2

Pyth, 34 30 Bytes

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

Probieren Sie es online aus.

Berechnet abs (a * (df) + c * (fb) + e * (bd)) / 2 aus Eingabe a, b, c, d, e, f.

Sam Cappleman-Lynes
quelle
2

R, 37 Bytes

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

Konvertiert den Koordinatenvektor in eine Matrix und setzt eine Reihe von Einsen aufeinander.
Berechnet die Determinante und dividiert durch 2.
Gibt das absolute Ergebnis zurück. Wenn die Bestellung immer im Uhrzeigersinn war, abswäre das nicht erforderlich.

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

Python 2, 48 47 50 Bytes

Sehr einfach; folgt der Standardgleichung:

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

Die anderen, ähnlich einfachen Ansätze sind länger:

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

Pythons Zugang zu einer bestimmten Funktion erfolgt über Numpy .

Dank an muddyfish für 1 Byte und xnor für das Abfangen eines Fehlers.

Celeo
quelle
Sie können die 0von 2.0zu verlassen2.
Blue
Ganz richtig, @muddyfish, danke!
Celeo
Ist das Python 2 oder 3? Division funktioniert je nach Version unterschiedlich ...
mbomb007
Klargestellt, @ mbomb007.
Celeo
1
Sie brauchen eine abs, um die Antwort positiv zu machen.
Xnor
2

PHP, 77

Basierend auf der Antwort von @Yimin Rong hatte ich das Gefühl, dass ich es um ein paar Bytes verbessern könnte, indem ich einige Variablen verwende list()anstatt sie direkt $argvabzukürzen. Ebenfallsecho nicht einen Raum brauchen , wenn Trennzeichen zwischen Echo und das Ding ist Echo wird.

echo$variable;, echo(4+2);Und echo'some string';sind gleichermaßen gültig , währendechofunction($variable) verwirrt PHP.

Andererseits habe ich auch hinzugefügt abs(), um mathematisch genau zu sein, da einige Kombinationen von Scheitelpunkten "negative Fläche" ergaben.

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

Sie können es über CLI ausführen

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
quelle
2

AWK - 51 42 Bytes

AWK hat keine eingebauten absso verwenden, um sqrt(x^2)zu ersetzen.

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

Speichern als area.awkund verwenden als echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, z

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

quelle
1

PowerShell, 70 Bytes

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

Verwendet die gleiche Standardformel wie andere Lösungen. Pro Frage wird davon ausgegangen, dass das Array vorbestückt ist, z $t=(1,2,4,2,3,7). Aber doof , töten die $und die []Syntax dieses ...

AdmBorkBork
quelle
Ihr Kommentar zur Strafe durch die Verwendung $und Ihre []Anregung haben mich dazu inspiriert, eine AWK-Lösung auszuprobieren, die in ihrer Länge nicht unumstritten ist!
1

Gleichstrom , 52 Bytes

Angenommen, die Eingabe befindet sich im Register t als: x1 y1 x2 y2 x3 y3mit x1am Anfang des tStapels.

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

Dabei wird die folgende Formel für die Fläche verwendet:

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

Und für eine schnelle Aufschlüsselung des Prozesses:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: Set Dezimalgenauigkeit bis 1 Stelle, Verschieben Teile des Stapels tzu dem Hauptstapel und verschiedene Teile des Hauptstapels zu anderen Registern für die Speicherung (bewegen ddupliziert die Oberseite des Hauptstapels, rkehrt sich die oberen beiden Elemente des Hauptstapels, L/lBewegung / Kopie aus dem angegebenen Register an main,s Verschiebt den oberen Bereich des Hauptstapels in das angegebene Register.)

    Main: y3 x3 y2 x1

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

  • la lc lb lt la: Die oben auf den Stapel in den Registern kopieren a, c, b, t, und aauf den Hauptstapel in dieser Reihenfolge

    Main: y1 y3 x2 y2 y1 y3 x3 y2 x1

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

  • - * sd: Berechnen ((y3-y1)*x2)und Put - Ergebnis in d(Register a, b, c, und tnicht mehr verwendet werden , so dass ich sie nun aus der Liste der Stapel fallen würde)

    Main: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *: berechnen ((y1-y2)*y3)und ((y2-x3)*x1); Speichern Sie die ersteren ine und lassen Sie die letzteren auf dem Hauptstapel

    Main: ((y2-x3)*x1)

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

  • le ld + +: Kopieren Sie die Oberseite des Registers eund din den Hauptstapel. Berechnen Sie die Summe der obersten 2 Stapelwerte (drücken Sie das Ergebnis zweimal zurück in den Hauptstapel)

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

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

  • 2 /: Push 2 auf Hauptstapel teilen auf Stapel 2. Werte durch die 1. ( dund enicht mehr verwendet werden, so dass sie aus der Liste von Stapeln dropping)

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

Wenn Sie den Wert im Stapel neu anordnen, sehen Sie, dass er der Formel oben in dieser Erklärung entspricht: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: Druckt die Oberseite des Hauptstapels für die Ausgabe.
Schnarchfrosch
quelle