计算物体的体积


18

您可以根据一组给定的尺寸确定对象的体积:

  • 球体的体积可以使用一个数字确定,半径(r
  • 圆柱体的体积可以使用两个数字确定,即半径(r)和高度(h
  • 可以使用三个数字(长(l),宽(w)和高(h))确定盒子的体积
  • 可以使用四个数字(边长(a, b, c)和高度(h))确定不规则三角形棱锥的体积。

面临的挑战是在以下输入之一的情况下确定对象的体积:

  • 单个数字(r)(r, 0, 0, 0)=>V = 4/3*pi*r^3
  • 两个数字(r, h)(r, h, 0, 0)=>V = pi*r^2*h
  • 三个数字(l, w, h)(l, w, h, 0)=>V = l*w*h
  • 四个数字(a, b, c, h)=> V = (1/3)*A*hAHeron公式给出A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

规则和说明:

  • 输入可以是整数和/或小数
  • 您可以假设所有输入尺寸均为正
  • 如果Pi是硬编码的,则必须精确到:3.14159
  • 输出必须至少包含6个有效数字,但可以用较少的数字准确表示的数字除外。您可以将输出3/40.75,但4/3必须为1.33333(可以输入更多数字)
    • 如何舍入不正确的值是可选的
  • 无效输入的行为未定义
  • 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 Griffin

@StewieGriffin Varargs和使用动态大小的数组是我的语言的痛苦(至少对我来说,这是一个初学者)。我可以提供四个函数来处理每个arg计数吗?

您可以有一个固定大小的数组,如果需要,可以将最后一个元素设置为零。我认为那应该涵盖它吗?或者您可以像Haskell答案中那样重载函数。您不能使用不同的名称来使用不同的功能。
Stewie Griffin

Answers:


4

MATL57 53 51 44字节

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

输入是具有1、2、3或4个数字的数组。

在线尝试!

说明

代替使用嵌套if循环(这在字节方面是昂贵的),它可以为任何输入计算四个可能的结果,然后根据输入长度选择适当的结果。

在计算结果时,即使其中只有一个有效,其他的也无法给出错误。例如,这意味着不允许索引输入的第四个元素,因为输入的元素可能少于四个。

                    % 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

您正在使用Heron公式的什么形式?
Addison Crump

@CoolestVeto具有半周长的那个。从这里开始的
Luis Mendo

干得好@DonMuesli。我在MATLAB中仅使用了“仅” 34个字节来管理它=)
Stewie Griffin

9

Vitsy,49个字节

我以为您已经把这个递给了我,但是我发现一个未解决的错误可以解决。不过并没有伤害我。

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

基本上,对于不同的功能,输入是一定长度的,您可以将执行此操作的方法语法输入给我。所以,是的,成功!

说明,一次一行:

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.

输入被接受为命令行参数,与出现在问题中的方向完全相反,没有尾随零。

在线尝试!

顺便说一句,这是目前正在开发中的东西。

带有Vitsy软件包的Java

请注意,该程序包正在进行中。这只是为了说明将来的工作方式(尚未上传有关此文件的文档),并且公开说明,仅作文字翻译:

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
绝对是工作的正确工具
Mego

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'3

你是绝对正确的。谢谢!
乔什(Josh)

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
用数学吗?似乎是合法的。
Addison Crump

Chrome 48出现此错误,Uncaught SyntaxError: Unexpected token =(指的是Z=a*a
Patrick Roberts

@PatrickRoberts使用Firefox。它允许在lambda中使用默认参数。
科纳·奥布莱恩

我似乎无法使用4-arg版本...并且您从不使用的值h,这似乎有些疏忽。
尼尔

@Neil Huh,是的。我需要再次查看该公式,Stewie删除了他的评论……
Conor O'Brien

3

Haskell 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(因此,基本上是FloatDouble)。

为简洁起见,不会赢得任何竞赛。但是请注意它的可读性。即使您不太了解Haskell,也可以很容易地知道它的作用。Haskell的模式匹配语法使定义奇怪的函数非常容易,这些函数根据输入的形状执行完全不同的操作。


1
(1/3)*(1/4)*h,,为什么不h/12呢?为您节省很多字节!
Stewie Griffin

1
而且,Conor使用的Heron eq的变体似乎要短得多。
Stewie Griffin

@StewieGriffin显然是的。: - }
MathematicalOrchid

Haskell仅对中缀数学可读,但我认为不可读。然后你进入.,并#$它成为数学汤。

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个字节!

我们接受四个输入,然后基于它们以相反的顺序逐步索引到伪三元语句中。例如,外部(..., ...)[!$h]测试是否存在第四输入。如果是这样,则!$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

CJam,67 66字节

q~0-_,([{~3#4*P*3/}{~\_**P*}{:*}{)\a4*(a\[1W1]e!..*+::+:*mq*C/}]=~

我会尽快将其缩短。在线尝试

解释来了。


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)

功能一:

ª*╦*
ª     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
多么疯狂的变量:-)是的,这似乎很难进一步缩短
Luis Mendo

也许添加一个链接以在线尝试?ideone.com/6VZF9z
Luis

0

3 2,127个 119 116字节

感谢某人迈戈所有他们与高尔夫的帮助。当我借用他们的部分答案时,也应归功于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码,仅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。
CalculatorFeline

您不能替换#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完全忘记了缩短功能名称。不过,不会有太大帮助。
2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.