三角形の面積


16

もう1つの簡単な課題です。

あなたのタスク

x座標とy座標の3つのペアを含み、それらの内部に形成される三角形の面積を計算する入力を受け取るプログラムまたは関数を作成します。計算方法を思い出せない人のために、ここで見つけることができます。

例:

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

Wolfram Alphaで見る

考慮事項:

  • 入力は、10を基数とする6つの正の整数です。
  • 入力は合理的な形式であると想定できます
  • ポイントは常に有効な三角形を形成します。
  • 入力がなどの変数に既に保存されていると仮定できますt
  • バイト単位の最短コードが勝ちです!

編集:混乱を避けるため、現在のコードを危険にさらすことなく入力を処理する方法を簡略化しました。

プログラム/関数は有効な領域を出力する必要があるため、出力として負の数を与えることはできません


1
再:あなたの編集。それは、私が実際のペアの配列(たとえば、[[1, 2], [4, 2], [3, 7]])を持つことができることを意味しTますか?
デニス

4
私はまだ混乱しています。投稿には、まだ「3ペア」と「6 ...整数」の両方が記載されています。いずれかを削除すると、一部の回答が無効になることに注意してください。
xnor

1
投稿して回答した後に質問が変わるのが嫌いです。しかし、今回はさらに2バイト節約できるので
大丈夫です-edc65

1
それらを3つのペアとして取り込むことができる場合、それらを多次元配列として取り込むことができますか?つまり、[1 2;4 2;3 7](ジュリア構文を使用して)?
グレンO

2
@YiminRong定義上、三角形の面積を負にすることはできません。ポイントの順序は関係ありません
。– Rainbolt

回答:


16

CJam、18 16バイト

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

CJamインタープリターでオンラインで試してください。

考え

ウィキペディアで述べたように、三角形の面積は[[0 0] [x y] [z w]]として計算できます|det([[x y] [z w]])| / 2 = |xw-yz| / 2

一般的な三角形の[[a b] [c d] [e f]]場合、最初の頂点を原点に変換し、三角形を取得[[0 0] [c-a d-b] [e-a f-b]]できます。三角形の面積は上記の式で計算できます。

コード

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

JavaScript(ES6)42 .44。

編集入力形式が変更され、2バイトを保存できます

配列をパラメーターとして受け取り、計算された値を返す匿名関数。

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

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
標準パラメーターとして値を取得し、配列の作成時に2文字を節約することはできませんでしたか?
Mwr247

@ Mwr247チャレンジが言うThe input will be a vector with six base 10 positive integers.
edc65

あぁ。最初は、入力自体が配列に制限されているため、各ペアが座標ベクトル(Wolframの例など)を構成することを意味しているため、他の形式を使用できると解釈していました。今より理にかなっています。
Mwr247

@ Mwr247今あなたは正しいです
-edc65

8

ジュリア、32バイト

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

クロス積の適切な項のマトリックスを構築しdet、結果の値を取得するために使用し、負の値を処理するために絶対値を取得し、平行四辺形ではなく三角形であるため2で除算します。


7

Matlab / Octave、26バイト

私はこれまでに組み込まれたこれについて知りませんでした=)

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

6

Java、79 88バイト

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

基本的な式を使用するだけで、特別なことはありません。

編集:絶対値を取るのを忘れた:(


実行可能にする必要はありませんか?
downrep_nation

3
この例は関数呼び出しを示しているだけであり、これは比較的通常のデフォルトです。
ジオビット

2
質問ごとに、•入力が「t」などの変数にすでに保存されていると仮定できます。だから、それでreturn(t[0]*(t[3]...十分でしょうか?
AdmBorkBork

@TimmyDはそれをやって日陰に感じるが、それはです 62バイトにそれをダウンさせます。うーん...少なくとも今のところはそのままにしておきます。
ジオビット

5

Minkolang 0.8、34バイト

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

誰でも卵が欲しいn0g

説明

とても簡単です。式を使用し|(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バイト

無名関数を宣言します:

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

例:

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

gは何をしますか?
レベルリバーセント

@steveverrill何もない、私はただのばかだ。修正...
mınxomaτ


3

PHP – 68 88 89バイト

素晴らしい指針をくれたMartjinに感謝します!

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

それを使用するには、area.phpこのコンテンツでファイルを作成し、余分な行が仕様の変数t部分にデータが保存されていると仮定し、最後に␍がキャリッジリターンを追加するので、出力がきれいで分離されます:

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

次に、コマンドラインで座標を指定しますx₁ y₁ x₂ y₂ x₃ y₃(例:

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

「入力は既になどの変数に保存されていると仮定できますt。」$a-> $t$a=$argv;9バイトの保存を削除
-Martijn

その後、に置き換え<?php echo<?=、さらに7バイトを節約します。
マーティン

これはPHP4.1でありregister_globals=Onphp.iniファイルに含まれていると言えます(デフォルト)。php.net/manual/en/security.globals.phpで
Ismael Miguel


2

R、37バイト

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

座標のベクトルを行列に変換し、1の行に追加します。
行列式を計算し、2で除算し
ます。絶対結果を返します。注文が常に時計回りである場合は、abs必要ありません。

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

2

パイソン2、48の 47 50バイト

非常に簡単です。標準方程式に従います。

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

他の同様に単純なアプローチはより長くなります:

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

Pythonの確定関数へのアクセスはnumpyを介して行われます。

1バイトのmuddyfishと、エラーをキャッチしてくれたxnorに感謝します。


あなたが削除することができます0から2.0休暇に2.
ブルー

@muddyfish、ありがとう!
Celeo

これはPython 2または3ですか?除算はバージョンによって異なります
...-mbomb007

明確化、@ mbomb007。
セレオ

1
あなたabsは答えを肯定的にする必要があります。
xnor

2

PHP、77

@Yimin Rongの回答に基づいて、いくつかの変数を短縮するlist()ためにストレートではなく使用することで、数バイト改善できると感じました$argv。また、echoエコーとエコーさのものの間の区切り文字がある場合はスペースを必要としません。

echo$variable;echo(4+2);echo'some string';のに対し均等に有効なechofunction($variable)混乱のPHP。

一方、abs()頂点のいくつかの組み合わせにより「負の領域」が得られたため、数学的に正確になるように追加しました

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

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バイト

AWKには組み込み機能がないabsためsqrt(x^2)、代わりに使用します。

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

名前を付けて保存しarea.awkecho x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk、たとえば、

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

1

PowerShell、70バイト

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

他のソリューションと同じ標準式を使用します。質問ごとに、配列があらかじめ設定されていると仮定し$t=(1,2,4,2,3,7)ます。しかし、ooof$および[]構文はこれを殺します...


使用してからのペナルティについてコメント$とは、[]長さによって、競争ではなく、AWKソリューションをしようとする私を触発!

1

dc、52バイト

入力が次のようにレジスタにあるt と仮定します:x1 y1 x2 y2 x3 y3with のスタックのx1先頭t

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

これは、面積に次の式を使用します。

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

そして、プロセスの簡単な内訳のために:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r:1つの場所に小数精度セット内のスタックの移動部t(メインスタックおよび保存のために他のレジスタにメインスタックの様々な部分を移動させるにはd、メインスタックの上部を複製rメインスタックの上位2つの要素を反転、L/l移動/指定されたレジスタからメインにコピーし、sメインスタックの先頭を指定されたレジスタに移動します)

    メイン: y3 x3 y2 x1

    a:y1、b:x2、c:y2、t:y3

  • la lc lb lt la:レジスタのスタックのトップをコピーacbt、及びaそのための主要スタックへ

    メイン: y1 y3 x2 y2 y1 y3 x3 y2 x1

    a:y1、b:x2、c:y2、t:y3

  • - * sd:計算((y3-y1)*x2)中とプット結果d(レジスタはabc、とt私は今、スタックのリストからそれらをドロップしますので、使用されなくなりました)

    メイン: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *:計算((y1-y2)*y3)および((y2-x3)*x1); e前者をメインスタックに保存し、後者をメインスタックに残します

    メイン: ((y2-x3)*x1)

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

  • le ld + +:レジスタのコピー上部ed二回メインスタックに、トップ2のスタック値の計算和(メインスタックに結果背中を押します)

    メイン: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

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

  • 2 /メインスタックにプッシュ2、第によりスタック上の第2の値を分割しない(dおよびeスタックのリストからそれらを落とし、もはや使用されています)

    メイン: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

スタック上の値を並べ替えると、この説明の先頭にある式と同等であることがわかります。 (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p:メインスタックの先頭を出力します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.