オブジェクトの体積を計算する


18

特定の次元セットに基づいてオブジェクトの体積を決定できます。

  • 球体の体積は、半径(r)という1つの数値を使用して決定できます。
  • 円柱の体積は、半径(r)と高さ(h)の2つの数値を使用して決定できます。
  • ボックスの容積は、長さ(l)、幅(w)、高さ(h)の3つの数値を使用して決定できます。
  • 不規則な三角ピラミッドの体積は、辺の長さ(a, b, c)と高さ(h)の4つの数値を使用して決定できます。

課題は、次の入力のいずれかを与えられたオブジェクトのボリュームを決定することです。

  • 単一の番号(r)または(r, 0, 0, 0)=>V = 4/3*pi*r^3
  • 2つの数字(r, h)または(r, h, 0, 0)=>V = pi*r^2*h
  • 3つの数字(l, w, h)または(l, w, h, 0)=>V = l*w*h
  • 4つの数字(a, b, c, h)=> V = (1/3)*A*h、ここでHeronの式でA与えられます:A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

規則と説明:

  • 入力は整数と小数の両方にすることができます
  • すべての入力ディメンションが正であると仮定できます
  • Piがハードコーディングされている場合は、最大で正確でなければなりません3.14159
  • より少ない桁で正確に表現できる数値を除き、出力には少なくとも6桁の有効数字が必要です。3/4として出力することができますが0.75、する4/3必要があります1.33333(より多くの数字はOK)
    • 不正確な値を丸める方法はオプションです
  • 無効な入力の動作は未定義です
  • I / Oの標準ルール。入力は、リストまたは個別の引数にすることができます

これはコードゴルフであるため、バイト単位の最短ソリューションが勝ちます。

テストケース:

calc_vol(4)
ans =  268.082573106329

calc_vol(5.5, 2.23)
ans =  211.923986429533

calc_vol(3.5, 4, 5)
ans =  70

calc_vol(4, 13, 15, 3)
ans =  24

関連するが異なる


1
ディメンションの順序は、質問に記載されている順序である必要がありますか?
Mego


@Mego、あなたは...選ぶことができる
Stewieグリフィン

@StewieGriffin Varargsと動的にサイズ変更された配列を取得することは、私の言語(少なくとも私にとっては初心者)にとっては苦痛です。各引数カウントを処理する4つの関数を提供できますか?

必要に応じて、最後の要素をゼロに設定した固定サイズの配列を使用できます。それでカバーできると思う?または、Haskellの回答のように関数をオーバーロードできます。異なる名前の異なる関数を持つことはできません。
スチューウィーグリフィン

回答:


4

MATL57 53 51 44バイト

3^4*3/YP*GpG1)*YP*GpG0H#)ts2/tb-p*X^3/*XhGn)

入力は、1、2、3、または4つの数字の配列です。

オンラインでお試しください!

説明

ifバイトの点で高価なネストされたループを使用する代わりに、任意の入力に対して4つの可能な結果を​​計算し、入力長に応じて適切な結果を選択します。

結果を計算するとき、そのうちの1つだけが有効である必要がありますが、他はエラーを与えることができません。これは、たとえば、入力の4番目の要素のインデックスが許可されないことを意味します。これは、入力の要素が4つ未満になる可能性があるためです。

                    % take input implicitly
3^4*3/YP*           % compute a result which is valid for length-1 input:
                    % each entry is raised to 3 and multiplied by 4/3*pi
G                   % push input
pG1)*YP*            % compute a result which is valid for length-2 input:
                    % product of all entries, times first entry, times pi
G                   % push input
p                   % compute a result which is valid for length-3 input:
                    % product of all entries
G                   % push input
0H#)ts2/tb-p*X^3/*  % compute a result which is valid for length-4 input:
                    % shorter version of Heron's formula applied on all
                    % entries except the last, times last entry, divided by 3
Xh                  % collect all results in a cell array
G                   % push input
n)                  % pick appropriate result depending on input length
                    % display implicitly

ヘロンの式のどの表現を使用していますか?
アディソンクランプ

@CoolestVetoセミペリメーターを持つもの。ここ
ルイスメンドー

よくできました@DonMuesli。私は、MATLABでさらに34バイトだけを使用して管理しました=)
Stewie Griffin

9

Vitsy、49バイト

あなたはこれを皿の上で私に手渡したと思っていましたが、回避すべき未解決のバグを見つけました。しかし、私を傷つけませんでした。

lmN
3^43/*P*
2^*P*
**
v:++2/uV3\[V}-]V3\*12/^v*3/

基本的に、さまざまな機能の入力が一定の長さであるため、このようなことを行うためのメソッド構文をスプーンで送ってくれます。だから、いや、成​​功!

説明、一度に1行:

lmN
l   Get the length of the stack.
 m  Go to the line index specified by the top item of the stack (the length).
  N Output as a number.

3^43/*P*
3^
          Put to the power of 3.
  43/*    Multiply by 4/3.
      P*  Multiply by π

2^*P*
2^     Put to the second power.
  *    Multiply the top two items.
   P*  Multiply by π

**
**     Multiply the top three items of the stack.

v:++2/uV3\[V}-]V3\*12/^v*3/
v                            Save the top item as a temp variable.
 :                           Duplicate the stack.
  ++                         Sum the top three values.
    2/                       Divide by two.
      u                      Flatten the top stack to the second to top.
       V                     Capture the top item of the stack (semiperimeter) 
                             as a permanent variable.
        3\[   ]              Do the stuff in the brackets 3 times.
           V}-               Subtract the semiperimeter by each item.
               V             Push the global var again.
                3\*          Multiply the top 4 items.
                   12/^      Square root.
                       v*    Multiply by the temp var (the depth)
                         3/  Divide by three.

入力は、質問に現れるのとまったく逆のコマンドライン引数として受け入れられ、末尾のゼロはありません。

オンラインでお試しください!

余談ですが、現在開発中のものがあります。

JavaとVitsyパッケージ

このパッケージは作業中です。これは、これが将来どのように機能するかを示すためのものであり(このドキュメントはまだアップロードされていません)、ゴルフではなく、文字通りの翻訳です:

import com.VTC.vitsy;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;

public class Volume {
    public static void main(String[] args) {
        Vitsy vitsyObj = new Vitsy(false, true);
        vitsyObj.addMethod(new Vitsy.Method() {
            public void execute() {
                vitsyObj.pushStackLength();
                vitsyObj.callMethod();
                vitsyObj.outputTopAsNum();
            }
        });
        vitsyObj.addMethod(new Vitsy.Method() {
            public void execute() {
                vitsyObj.push(new BigDecimal(3));
                vitsyObj.powerTopTwo();
                vitsyObj.push(new BigDecimal(4));
                vitsyObj.push(new BigDecimal(3));
                vitsyObj.divideTopTwo();
                vitsyObj.multiplyTopTwo();
                vitsyObj.pushpi();
                vitsyObj.multiplyTopTwo();
            }
        });
        vitsyObj.addMethod(new Vitsy.Method() {
            public void execute() {
                vitsyObj.push(new BigDecimal(2));
                vitsyObj.powerTopTwo();
                vitsyObj.multiplyTopTwo();
                vitsyObj.pushpi();
                vitsyObj.multiplyTopTwo();
            }
        });
        vitsyObj.addMethod(new Vitsy.Method() {
            public void execute() {
                vitsyObj.multiplyTopTwo();
                vitsyObj.multiplyTopTwo();
            }
        });
        vitsyObj.addMethod(new Vitsy.Method() {
            public void execute() {
                vitsyObj.tempVar();
                vitsyObj.cloneStack();
                vitsyObj.addTopTwo();
                vitsyObj.addTopTwo();
                vitsyObj.push(new BigDecimal(2));
                vitsyObj.divideTopTwo();
                vitsyObj.flatten();
                vitsyObj.globalVar();
                vitsyObj.push(new BigDecimal(3));
                vitsyObj.repeat(new Vitsy.Block() {
                    public void execute() {
                        vitsyObj.globalVar();
                        vitsyObj.rotateRight();
                        vitsyObj.subtract();
                    }
                });
                vitsyObj.globalVar();
                vitsyObj.push(new BigDecimal(3));
                vitsyObj.repeat(new Vitsy.Block() {
                    public void execute() {
                        vitsyObj.multiplyTopTwo();
                    }
                });
                vitsyObj.push(new BigDecimal(1));
                vitsyObj.push(new BigDecimal(2));
                vitsyObj.divideTopTwo();
                vitsyObj.powerTopTwo();
                vitsyObj.tempVar();
                vitsyObj.multiplyTopTwo();
                vitsyObj.push(new BigDecimal(3));
                vitsyObj.divideTopTwo();
            }
        });
        vitsyObj.run(new ArrayList(Arrays.asList(args)));
    }
}

1
間違いなく仕事に
最適な

5

C、100 97バイト

#define z(a,b,c,d) d?d*sqrt(4*a*a*b*b-pow(a*a+b*b-c*c,2))/12:c?a*b*c:3.14159*(b?a*a*b:4/3.*a*a*a)

編集1:不要な小数を削除.、Immibisに感謝!


2
4./3.ただできない4/3.?そして、することができます2.し、12.ちょうどなる212
user253751

あなたは絶対に正しいです。ありがとう!
ジョシュ

4

JavaScriptのES6、129 126 125 116 114 90バイト

Stewie Griffinのおかげで、素晴らしい数式で大量のバイト(9)を節約できました!入力はゼロ以外でなければならないため、variable?、定義チェックには十分です。

with(Math){(a,b,c,h,Z=a*a)=>h?sqrt(4*Z*b*b-(D=Z+b*b-c*c)*D)/4:c?a*b*c:b?PI*Z*b:4/3*PI*Z*a}

試してみてください!

with(Math){Q = (a,b,c,h,Z=a*a)=>h?sqrt(4*Z*b*b-(D=Z+b*b-c*c)*D)/4:c?a*b*c:b?PI*Z*b:4/3*PI*Z*a}
console.log = x => o.innerHTML += x + "<br>";

testCases = [[4], [5.5, 2.23], [3.5, 4, 5], [4, 13, 15, 3]];
redo = _ => (o.innerHTML = "", testCases.forEach(A => console.log(`<tr><td>[${A.join(", ")}]` + "</td><td> => </td><td>" + Q.apply(window, A) + "</td></tr>")));
redo();
b.onclick = _ => {testCases.push(i.value.split(",").map(Number)); redo();}
*{font-family:Consolas,monospace;}td{padding:0 10px;}
<input id=i><button id=b>Add testcase</button><hr><table id=o></table>


5
数学で?スジは通ってるようだ。
アディソンクランプ

Chrome 48でのこのエラーUncaught SyntaxError: Unexpected token =(を参照Z=a*a
パトリックロバーツ

@PatrickRoberts Firefoxを使用します。ラムダ内のデフォルトパラメータを許可します。
コナーオブライエン

4-argバージョンを動作させることはできないようですが...の値を使用することはありませんがh、これは少し見落としがちです。
ニール

@ニール・フー、本当。もう一度その式を見る必要があります、Stewieは彼のコメントを削除しました...
Conor O'Brien

3

ハスケル、 114 109 107 101 99バイト

v[r]=4/3*pi*r^3
v[r,h]=pi*r^2*h
v[x,y,z]=x*y*z
v[a,b,c,h]=h/12*sqrt(4*a^2*b^2-(a^2+b^2-c^2)^2)

数字のリストを取り、ボリュームを返します。のように呼ぶ

v[7]

球体などの場合。関数は、実装するすべての型に対して多相sqrt的です(つまり、基本的にFloatまたはDouble)。

簡潔さのためにコンテストに勝つつもりはありません。しかし、それがどれほど読みやすいかに注意してください。Haskellを実際に知らなくても、Haskellが何をするのか簡単にわかります。Haskellのパターンマッチング構文により、入力の形状に応じてまったく異なることを行う奇妙な関数を簡単に定義できます。


1
(1/3)*(1/4)*h、、、なぜh/12ですか?多くのバイトを節約できます!
スチューウィーグリフィン

1
また、Conorが使用するHeronのeqのバリアントは、はるかに短いようです。
スチューウィーグリフィン

@StewieGriffinどうやらそうです。:-}
MathematicalOrchid

Haskellは中置数学でしか読めませんが、読めません。次に、あなたが入る.し、#そして$、それはMathematicaのスープになります。

3

PowerShell、165 161バイト

param($a,$b,$c,$h)((($h/12)*[math]::Sqrt(($a+$b+$c)*(-$a+$b+$c)*($a-$b+$c)*($a+$b-$c))),(($a*$b*$c),((($p=[math]::PI)*$b*$a*$a),($p*$a*$a*$a*4/3))[!$b])[!$c])[!$h]

だから...多くの...ドル...(161文字のうち31文字が $、コードの19.25%である)...しかし、Stewie Griffinのおかげで4バイト節約された!

4つの入力を取り込んでから、それらに基づいて逆順で擬似三項ステートメントに徐々にインデックスを付けます。たとえば、外部(..., ...)[!$h]は4番目の入力が存在するかどうかをテストします。その場合、!$h意志は等しく0なり、前半が実行されます(不規則な三角錐の体積)。それ以外の場合、!$hwith $h = $null(初期化されていないため)は等しくなります1ためため、後半に進み[!$c]ます。

これは、おそらくより短い式であるため(たとえば) CᴏɴᴏʀO'Bʀɪᴇɴが使用しているが、実際には2バイト長の不足にPowerShellのおかげである^オペレータを...唯一の本当の節約はから来て(1/3)*(1/4)*A*$hゴルフをA*$h/12し、$p長い[math]::PI呼び出しの代わりに数バイトを保存するように後で設定します。



1

真剣に、65 59 55バイト

`kd@;Σ½╗"╜-"£Mπ╜*√*3@/``kπ``ª*╦*``3;(^/4*╦*`k,;lD(E@i(ƒ

オンラインでお試しください!

説明

これはすごいです。説明を複数の部分に分割します。

本体:

`...``...``...``...`k,;lD(E@i(ƒ
`...``...``...``...`k            push 4 functions to a list
                     ,;lD        push input, len(input)-1
                         (E      get the function at index len(input)-1
                           @i(   flatten the input list
                              ƒ  execute the function

機能0:

3;(^/4*╦*
3;(^       push 3, r^3
    /      divide (r^3/3)
     4*    multiply by 4 (4/3*r^3)
       ╦*  multiply by pi (4/3*pi*r^3)

機能1:

ª*╦*
ª     r^2
 *    multiply by h (r^2*h)
  ╦*  multiply by pi (pi*r^2*h)

機能2:

kπ  listify, product (l*w*h)

機能3(21バイト、プログラムの長さのほぼ半分!)

kd@;Σ½╗"╜-"£Mπ╜*√*3@/
kd@                    listify, dequeue h, bring [a,b,c] back on top
   ;Σ½                       dupe, sum, half (semiperimeter)
      ╗                push to register 0
       "╜-"£M          map: push s, subtract (s-x for x in (a,b,c))
             π         product
              ╜*√      multiply by s, sqrt (Heron's formula for area of the base)
                 *3@/  multiply by h, divide by 3 (1/3*A*h)

1

Matlab、78バイト

@(a,b,c,d)pi*a^2*(4/3*a*~b+b*~c)+a*b*c*~d+d/12*(4*a^2*b^2-(a^2+b^2-c^2)^2)^.5;

これより短くなることはありません。~b~cおよび~d0、各次元がゼロ以外の場合です。次元がゼロの数式では、ゼロが得られます。そうすれば、各式を単純に合計できます。番号ifelse必須です。

このように呼び出します(またはここでオンラインで試してください):

g=@(a,b,c,d)pi*a^2*(4/3*a*~b+b*~c)+a*b*c*~d+d/12*(4*a^2*b^2-(a^2+b^2-c^2)^2)^.5;

g(4,0,0,0)
ans =  268.082573106329

g(5.5,2.23,0,0)
ans =  211.923986429533

g(3.5,4,5,0)
ans =  70

g(4,13,15,3)
ans =  24

1
なんて変数の狂気:-)はい、これをさらに短くするのは難しいようです
ルイスメンドー

オンラインで試すためのリンクを追加しますか?ideone.com/6VZF9z
ルイスメンドー

0

Pythonの3 2、127 119 116バイト

功績誰かMEGOゴルフのすべての彼らの助けのため。また、CᴏɴᴏʀO'BʀɪᴇɴJoshの功績を称えました。これに対する回答の一部を借りたからです。

def v(a,b,c,d):z=a*a;P=3.14159;print filter(int,[max(0,(4*z*b*b-(z+b*b-c*c)**2))**.5*d/12,a*b*c,P*z*b,P*z*a*4/3])[0]

ゴルフをしていない:

def v(a, b, c, d):
    z = a*a
    p = 3.14159
    s = filter(int,[max(0,(4*z*b*b-(z+b*b-c*c)**2))**.5*d/12,a*b*c,P*z*b,P*z*a*4/3])
    print s[0]

もっとゴルフ:def v(a,b,c,d):z=a*a;p=355/113;return[x for x in[(4*z*b*b-(z+b*b-c*c)**2)**.5*d/12,a*b*c,p*z*b,p*z*a*4/3]if x][0]、入力に0s が埋め込まれていると仮定します。
ASCIIのみ

あなたの代わりにPythonの2を使用する場合も、あなたが行うことができますdef v(a,b,c,d):z=a*a;P=3.14159;return filter(int,[(4*z*b*b-(z+b*b-c*c)**2)**.5*d/12,a*b*c,P*z*b,P*z*a*4/3])[0]
ASCIIのみ

0

Mathematica、114(103)

純粋な機能:114

Which[(l=Length@{##})<2,4.Pi/3#1^3,l<3,#1^2.Pi#2,l<4,#1#2#3,l<5,(4#1^2#2^2-(#1^2+#2^2-#3^2)^2)^.5#4/12]~Quiet~All&

ゴルフをしていない:

fun = Which[
  (l = Length@{##}) < 2,
    4. Pi/3 #1^3,
  l < 3,
    #1^2 Pi #2, 
  l < 4,
    #1 #2 #3, 
  l < 5,
    (4 #1^2 #2^2 - (#1^2 + #2^2 - #3^2)^2)^.5 #4/12
]~Quiet~All &

使用法:

fun[4]
268.083
fun[5.5, 2.23]
211.924
fun[3.5, 4, 5]
70.
fun[4, 13, 15, 3]
24.

名前付き関数が許可されている場合:103

f[r_]:=4.Pi/3r^3
f[r_,h_]:=r^2.Pi h
f[l_,w_,h_]:=l w h
f[a_,b_,c_,h_]:=(4a^2b^2-(a^2+b^2-c^2)^2)^.5h/12

使用法:

f[4]
268.083
f[5.5, 2.23]
211.924
f[3.5, 4, 5]
70.
f[4, 13, 15, 3]
24.

1
#1==#、私は思うQuiet[x_]:=Quiet[x,All](π(MacではAlt-P)は拡張ASCIIに収まる)。
電卓

あなたは置き換えることはできません#1 #2 #31##?忘れてはいけない#==#1
CalculatorFeline

0

係数、783バイト

まあ、これは永遠にかかりました。

USING: arrays combinators io kernel locals math math.constants math.functions quotations.private sequences sequences.generalizations prettyprint ;
: 1explode ( a -- x y ) dup first swap 1 tail ;
: 3explode ( a -- b c d ) 1explode 1explode 1explode drop ;
: spr ( r -- i ) first 3 ^ 4 3 / pi * swap * ;
: cyl ( r -- i ) 1explode 1explode drop 2 ^ pi swap * * ; : cub ( v -- i ) 1 [ * ] reduce ;
: A ( x a -- b d ) reverse dup dup dup 0 [ + ] reduce -rot 3explode neg + + -rot 3explode - + 3array swap 3explode + - 1array append 1 [ * ] reduce sqrt .25 swap * ;
: ilt ( a -- b c  ) V{ } clone-like dup pop swap A 1 3 / swap pick * * ;
: volume ( v -- e ) dup length { { [ 1 = ] [ spr ] } { [ 2 = ] [ cyl ] } { [ 3 = ] [ cub ] } { [ 4 = ] [ ilt ] } [ "bad length" throw ] } cond print ;

を呼び出し{ array of numbers } volumeます。


@StewieGriffin:PIは、関数の名前を短くすることを完全に忘れていました。しかし、あまり役に立ちません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.