四面体の表面積


16

チャレンジ

この課題は非常に簡単です。4つの3次元ポイントが与えられたら、それらが形成する四面体の表面積を計算します。これはなので、最短のコードが優先されます。標準的な抜け穴が適用されますが、4つのポイントが与えられた場合にこのタスクを実行する組み込み関数は禁止されるという追加の規定があります。

4つのポイントすべてが明確であり、STDINを介して1行に1ポイント与えられると仮定できます。各ポイントは、3つの16ビット符号なし整数で構成されます。3つのスペースで区切られた整数など、作業を簡単にする場合は、各ポイントの正確な形式を変更できます。ただし、各ポイントを別々の行に置くことは必須です。出力は、STDOUTを介して、少なくとも小数点以下2桁にする必要があります。

知らない人にとっては、四面体は4つの三角形の面で構成される3次元の立体です。

# input (format is up to you, see clarification above)
[23822, 47484, 57901]
[3305, 23847, 42159]
[19804, 11366, 14013]
[52278, 28626, 52757]

# output
2932496435.95

私の数学が間違っていることに気づいたら、メモを残してください。


@BetaDecayいいえ、アイデアは4つの別々の行でSTDINを介して入力されるということです。これを明確にするために質問を編集します。
確率論的14年

入力は可能[[list],[of],[lists]]ですか?
ホスゲン14年

@phosgene入力を読むことはチャレンジの一部だと思うので、ノーと言うつもりです。今後の課題では、入力仕様にもっと寛容になるように努力します。
確率論的14年

これは規則的または不規則な四面体ですか?
ジェームズウィリアムズ14年

@JamesWilliamsの投稿例は不規則です。プログラムは、通常の四面体を含むすべての入力を処理する必要があります。
ストカスティック14年

回答:


5

Python、198 178 161文字

V=eval('input(),'*4)
A=0
for i in range(4):F=V[:i]+V[i+1:];a,b,c=map(lambda e:sum((a-b)**2for a,b in zip(*e)),zip(F,F[1:]+F));A+=(4*a*b-(a+b-c)**2)**.5
print A/4

入力形式は質問のとおりです。

各面に隣接するエッジの長さを計算し、Heronの式を使用します。


4

Matlab / Octave 103

値は変数に格納されると仮定しますc。これは、三角形の面積がその2つの側面ベクトルの外積の半分の長さであるという事実を使用しています。

%input
[23822, 47484, 57901;
3305, 23847, 42159;
19804, 11366, 14013;
52278, 28626, 52757]



%actual code
c=input('');
a=0;
for i=1:4;
    d=c;d(i,:)=[];
    d=d(1:2,:)-[1 1]'*d(3,:);
    a=a+norm(cross(d(1,:),d(2,:)))/2;
end
a

各ポイントは、標準入力として個別の行に入力する必要があります。
DavidC 14年

Matlabには標準入力のようなものはないと最初は思っていましたが、コマンドウィンドウを介してこれをシミュレートするために使用できる関数を発見したため、他の言語でできるように入力を渡すことができます。
flawr 14年

面白い。これは、Mathematicaの使い方、同じコマンドですInput[]
DavidC

なぜこれが面白いと思いますか?「入力」は、これを行う関数のかなり一般的な名前のように思えます。
flawr 14年

昨日までは、私は本当に「標準入力」は何を意味するのか知りませんでした、と私はMathematicaは、私が愛用していたにも関わらず、「標準」の入力を持っていなかったことを考えInput[]InputString[]Import[]、とImportString[]
DavidC 14年

4

APL、59

f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺}
.5×.5+.*⍨(f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕

クロス積を計算して動作します

説明
1行目は、2つの引数(暗黙の名前付きおよび)を取り、暗黙的に長さ3の数値配列であると想定し、3dベクトルとして扱い、それらの外積の2乗の大きさを計算する関数を定義します。

                        ⊂⍺   # Wrap the argument in a scalar
                   1 2⌽¨     # Create an array of 2 arrays, by rotating `⊂⍺` by 1 and 2 places
             (⊂⍵)×           # Coordinate-wise multiply each of them with the other argument
        1 2-.⌽               # This is a shorthand for:
        1 2  ⌽               #   Rotate the first array item by 1 and the second by 2
           -.                #   Then subtract the second from the first, coordinate-wise
       ⊃                     # Unwrap the resulting scalar to get the (sorta) cross product
   +.×                       # Calculate the dot product of that...
      ⍨                      # ...with itself
f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺} # Assign function to `f`

2行目は残りを行います。

                         ⎕⎕⎕-⊂⎕ # Take 4 array inputs, create an array of arrays by subtracting one of them from the other 3
                       x←        # Assign that to x
                     4⍴          # Duplicate the first item and append to the end
                  2f/            # Apply f to each consecutive pair
            2-/x                 # Apply subtraction to consecutive pairs in x
          f/                     # Apply f to the 2 resulting arrays
         (f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕ # Concatenate to an array of 4 squared cross products
   .5+.*⍨                        # Again a shorthand for:
   .5  *⍨                        #   Take square root of each element (by raising to 0.5)
     +.                          #   And sum the results
.5×                              # Finally, divide by 2 to get the answer

象形文字なのか破損したdllファイルなのかわからない場合は、おそらくAPLになるでしょう。これらの記号のいくつかが何をするのか、もう少し説明していただけますか?私はそれを学びたいというわけではありませんが、一見曖昧なシンボル= P
flawr 14年

@flawr APLでのゴルフはほとんどアルゴリズム設計に帰着するため、私は通常これを行います。ほとんどの場合、問題に対する珍しいアプローチになるでしょう。しかし、ここでは「外積の計算」がアルゴリズムについて十分に伝えていると感じました。完全な説明が必要な場合は、今日後で説明します。
TwiNight 14年

クロス積を計算するという考えは明確でしたが、コード自体には何の手がかりもありません。そのため、コードのどの部分が素晴らしいことをするかについていくつかの言葉を考えましたが、もちろん、詳細な説明を書いてください!
flawr

3

Python 3、308 298 292 279 258 254

from itertools import*
def a(t,u,v):w=(t+u+v)/2;return(w*(w-t)*(w-u)*(w-v))**.5
z,x,c,v,b,n=((lambda i,j:(sum((i[x]-j[x])**2for x in[0,1,2]))**.5)(x[0],x[1])for*x,in combinations([eval(input())for i in">"*4],2))
print(a(z,x,v)+a(z,c,b)+a(b,v,n)+a(x,c,n))

これは以下を使用します:

  • 各行の長さを計算するためのピタゴラスの定理(3D)
  • 各三角形の面積を計算するヘロンの式

1
ソリューションのテストにも同じ方法を使用しました。ゴルフをしてみて、後で投稿する必要があります。
ストカスティック14年

1
あなたfor i in">"*4は賢い
確率論的14年

範囲関数でlen(i)を使用する代わりに、長さ3をハードコーディングできます。
ストカスティック14年

1
x**0.5代わりに、平方根を行う文字をさらにいくつか保存できますmath.sqrt(x)
Snorfalorpagus

1
次のdef a(t,u,v)ように1行入力することで2バイトを節約できますdef a(t,u,v):w=(t+u+v)/2;return(w*(w-t)*(w-u)*(w-v))**0.5
ベータ崩壊14年

2

Mathematica 168 154

これは、四面体のエッジの長さを見つけて使用します ヘロンの式をて面の面積を決定します。

t = Subsets; p = Table[Input[], {4}];
f@{a_, b_, c_} := Module[{s = (a + b + c)/2}, N[Sqrt[s (s - #) (s - #2) (s -#3)] &[a, b, c], 25]]
  Tr[f /@ (EuclideanDistance @@@ t[#, {2}] & /@ t[p, {3}])]

60文字のみを必要とするより直接的なルートがありますが、組み込み関数で各面の面積を計算する限り、ルールに違反しますArea

p = Table[Input[], {4}];
N[Tr[Area /@ Polygon /@ Subsets[p, {3}]], 25]


0

パイソン-260

私はあなた自身の質問への回答を投稿する際のエチケットが何であるかわかりませんが、彼女は私の解決策であり、私の例を検証するために使用しました。

import copy,math
P=[input()for i in"1234"]
def e(a, b):return math.sqrt(sum([(b[i]-a[i])**2 for i in range(3)]))
o=0
for j in range(4):p=copy.copy(P);p.pop(j);a,b,c=[e(p[i],p[(i+1)%3])for i in range(3)];s=(a+b+c)/2;A=math.sqrt(s*(s-a)*(s-b)*(s-c));o+=A
print o

laurencevsと同じ手順を使用します。


4
経験則として、特にスコアが低い場合は、視聴者のモチベーションを冷やさないために、数日待ってから自分の質問に答えることをお勧めします。
ブラックホール14年

いくつかのヒント:でいくつかのキャラクターを保存できますr=rangelambdaはより短いdefmath.sqrtに置き換えることができます(…)**.5p=copy.copy(P);p.pop(j);に短縮できますp=P[:j-1]+P[j:]A一度だけ使用されます。
Wrzlprmft 14年

0

C、303

不要な空白を除外します。ただし、ここで行うべきゴルフはまだたくさんあります(後で戻ってやってみようと思います。)でforループを宣言したのは初めてです。#define。でです。私はいつもループの数を最小化する方法を見つけました。

テストケースのOPと同じ答えを得るためにからに変更floatするdouble必要がありました。それ以前は、ラウンド300でした。

scanf 入力をスペースまたは改行で区切っても同じように機能するので、好きなだけ行をフォーマットすることができます。

#define F ;for(i=0;i<12;i++)
#define D(k) (q[i]-q[(i+k)%12])
double q[12],r[12],s[4],p,n;

main(i){
  F scanf("%lf",&q[i])
  F r[i/3*3]+=D(3)*D(3),r[i/3*3+1]+=D(6)*D(6)
  F r[i]=sqrt(r[i])
  F i%3||(s[i/3]=r[(i+3)%12]/2),s[i/3]+=r[i]/2
  F i%3||(p=s[i/3]-r[(i+3)%12]),p*=s[i/3]-r[i],n+=(i%3>1)*sqrt(p)   
  ;printf("%lf",n);       
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.