你圣诞节收到了多少礼物?


32

是的,多少,不是多少...

众所周知,大礼物比小礼物好得多。因此,礼物的价值应始终以总体积来衡量,而不是礼物的数量,重量甚至是组合价格。

由于不愿比较一个人得到的礼物数量,因此您不希望长篇幅的脚本在圣诞晚会上容易被他人看到和阅读。因此,您需要使脚本中的字节数最少。

您的任务很简单:创建一个程序,以任何合适的格式将尺寸列表作为输入,并输出礼物的总体积。每个礼物的尺寸可以是三个数字的集合,也可以是一个数字。如果输入为三个数字(L, W, H),则当前为长方体L x W x H。如果是单个数字(R),则表示当前半径为球形R

规则:

  • 它可以是完整程序或功能
  • 输入可以是任何方便的格式
    • 如果需要,一个球体可以用一个数字后跟两个零表示
    • 长方体将始终具有所有非零尺寸。
  • 输出应为单个十进制数
    • 只要显而易见的答案是什么,就可以接受其他输出
    • 输出必须在小数点后至少有两位数字
    • 如果数字大于1000,则输出可以采用标准格式/科学计数法。
    • 如果您的语言没有Pi常数,则答案应准确到9999.99。

例子:

((1,4,3),(2,2,2),(3),(4,4,4))
197.0973    // (1*4*3 + 2*2*2 + 4/3*pi*3^3 + 4*4*4)

(5)
523.5988

(5,0,0)
523.5988

排行榜

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


3
没有哪个女士在那些有趣的圆柱盒中戴帽子吗?
manatwork 2015年

2
@manatwork,不,所有女士都将获得圆顶硬礼帽,并且您可以轻松地将其戴入球形= P
Stewie Griffin

1
我认为(5)这只是部分示例,我们的代码只需要处理即可((5))
manatwork

2
如果我们选择的语言没有Pi常数,那么需要多少精度?
丹尼斯

1
@ manatwork,+和*可以,只要它们不表示您使用的语言的加法和乘法(或其他运算)即可。
Stewie Griffin

Answers:


10

果冻19 18字节

Zµ*3×1420÷339Ḣo@PS

在线尝试!

不幸的是,Jelly还没有π常数,并且矢量化器无法正确处理浮点数。

为了克服这些问题,我们不乘以4π/ 3,而是乘以1420并除以339。由于1420÷339 = 4.18879056…4π/ 3 = 4.18879020…,因此足够精确以符合规则。

最新版本的Jelly可以14字节的精度完成此任务。

Zµ*3×240°Ḣo@PS

在线尝试!

怎么运行的

Zµ*3×1420÷339Ḣo@PS  Left argument: A, e.g., [[1, 2, 3], [4, 0, 0]]

Z                   Zip A; turn A into [[1, 4], [2, 0], [3, 0]].
 µ                  Begin a new, monadic chain with zip(A) as left argument.
  *3                Cube all involved numbers.
    ×1420           Multiply all involved numbers by 1420.
         ÷339       Divide all involved numbers by 339.
                    This calculates [[4.19, 268.08], [33.51, 0], [113.10, 0]]
             Ḣ      Head; retrieve the first array.
                    This yields [4.19, 268.08].
                P   Take the product across the columns of zip(A).
                    This yields [6, 0].
              o@    Apply logical OR with swapped argument order to the results.
                    This replaces zeroes in the product with the corresponding
                    results from the left, yielding [6, 268.08].
                 S  Compute the sum of the resulting numbers.

非竞争版本使用×240°代替×1420÷339,乘以240并将乘积转换为弧度。


9

Haskell,40个字节

q[x]=4/3*pi*x^^3
q x=product x
sum.map q

用法示例:sum.map q $ [[1,4,3],[2,2,2],[3],[4,4,4]]-> 197.09733552923254

工作原理:对于输入列表中的每个元素:如果有一个元素,则x计算球体的体积,否则取product。总结一下。


1
这种计数字节的方法通常有效吗?我会说过p=sum.map q(然后被告知要使用p数字列表)
Leif Willerts 2015年

1
@LeifWillerts:最近有一个关于meta的主题,它允许未命名的函数在全局定义上进行中继。sum.map q是一个依赖于的未命名函数q,所以我想很好。
nimi

9

Pyth,19 18字节

sm|*Fd*.tC\ð7^hd3Q

1个字节,感谢丹尼斯

示范

输入格式为列表列表:

[[1,4,3],[2,2,2],[3,0,0],[4,4,4]]

只需将尺寸相乘即可计算出立方体积。如果结果为零,则计算球体体积。

球体常数4/3*pi以弧度表示为240度。.t ... 7将以度为单位的输入转换为弧度,并C\ð计算的代码点ð,即240。


7

Python 2,86 70字节

lambda i:sum(x[0]*x[1]*x[2]if len(x)>1 else x[0]**3*4.18879for x in i)

我得到的字节数为86,您是怎么得到的?
wnnmaw 2015年

另外,您可以通过手动输入pi的值来保存字节,最多可以使用以3.14159265358979323达到收支平衡
wnnmaw

@wnnmaw我忘了数导入-.-
TFeld

我相信您对pi的硬编码值有点过:)
wnnmaw 2015年

4
@wnnmaw不是Pi;是4Pi / 3。
丹尼斯

5

Mathematica,34个字节

Tr[1.##&@@@(#/.{r_}:>{4r^3/3Pi})]&

一个未命名的函数,它使用嵌套的长度列表并将卷作为实数返回。

我们首先用替换相应球体的体积中的单个值/.{r_}:>{4r^3/3Pi}。然后,将每个列表的内容乘以1.##&@@@。最后,我们使用来计算和作为向量的迹线Tr[...]


5

JavaScript(ES6),56

l=>l.map(([x,y,z])=>t+=y?x*y*z:x*x*x*4/3*Math.PI,t=0)&&t

明智的 .reduce版本是1字节长

l=>l.reduce((t,[x,y,z])=>t+(y?x*y*z:x*x*x*4/3*Math.PI),0)

您可以使用4.11879代替来保存几个字节4/3*Math.PI,因为这应该足够准确才能符合要求。
ETHproductions 2015年

@ETHproductions是的,但是In case your language doesn't have a Pi-constant,我的语言有一个PI常数,所以我不知道它是否符合条件
edc65

5

Python,49个字节

lambda l:sum(a*b*c or a**3*4.18879for a,b,c in l)

将球体的表示形式用作(a,0,0)。被视为长方体,其体积为0,在这种情况下,将使用球体体积。我不清楚常数需要多精确,所以我希望这足够了。


4

MATL,20字节

it!ptbw~)3^4*3/XT*hs

输入格式是一个矩阵,其中每行描述一个立方体或一个球体。球体仅由该行中的第一个数字定义;其他两个数字为零。因此,挑战的第一个例子是:

[1 4 3; 2 2 2; 3 0 0; 4 4 4]

这将使用当前版本的语言2.0.2,它比此挑战还早。

例子:

>> matl it!ptbw~)3^4*3/XT*hs
> [1 4 3; 2 2 2; 3 0 0; 4 4 4]
197.0973355292326

>> matl it!ptbw~)3^4*3/XT*hs
> [5 0 0]
523.5987755982989

说明:

i             % input matrix
t!            % duplicate and transpose: each object is now a column
p             % product of elements in each column
t             % duplicate                                               
b             % bubble up top-third element in stack                              
w             % swap top two elements in stack                                  
~             % logical 'not'. This gives logical index of speheres                 
)             % reference () indexing. This is a logical-linear index to get sphere radii
3^4*3/XT*     % formula for volume of spehere; element-wise operations
h             % horizontal concatenation                                
s             % sum                

3

Prolog,115100字节

码:

[]*0.
[[L,W,H]|T]*V:-W=0,X is 4*pi*L^3/3,T*Y,V is X+Y;X is L*W*H,T*Y,V is X+Y.
p(L):-L*V,write(V).

解释:

[]*0.
[[L,W,H]|T]*V:-W=0,                           % When 2nd dimension is 0
                  X is 4*pi*L^3/3,            % Calc volume of sphere
                  T*Y,                        % Recurse over list
                  V is X+Y                    % Sum volumes
                  ;                           % When we have a cube
                  X is L*W*H,                 % Calc cube volume
                  T*Y                         % Recurse over list
                  V is X+Y.                   % Sum volumes
p(L):-L*V,                                    % Get combined volume of list of lists
      write(V).                               % Print volume

例子:

p([[1,4,3],[2,2,2],[3,0,0],[4,4,4]]).
197.09733552923257

p([[5,0,0]]).
523.5987755982989

在这里在线尝试

编辑:通过定义二元谓词保存15个字节。


3

Perl,52岁 47字节

s/,/*/g||s@$@**3*4.18879@,$\+=eval for/\S+/g}{

46 + 1 for -p(这很常见;让我知道这里是否有所不同,我会进行更新)

用法:放入文件并 echo 1,4,3 2,2,2 3 4,4,4 | perl -p x.pl

有评论:

s/,/*/g                # x,y,z becomes x*y*z
||                     # if that fails,
s@$@**3*1420/339@      # x becomes x**3 * 1420/339
,                      # 
$\+=eval               # evaluate the expression and accumulate
for/\S+/g              # iterate groups of non-whitespace
}{                     # -p adds while(<>){...}continue{print}; resets $_

更新47感谢@Dennis使用此技巧节省了一些字节。


s/,/*/g||s@$@**3*4.18879@,$\+=eval for/\S+/g;}{保存一些字节。
丹尼斯

@丹尼斯谢谢!我之前尝试过$ \,但是重设$_成本也很多。仍不清楚为什么$_是在一个新的块复位,但..是$_块本地的while(<>){}
肯尼2015年

是的,$_是当前作用域的默认变量。在END块中,它是未定义的。
丹尼斯

2

CJam,24个 21字节

q~{3*)4P*3/*+3<:*}%:+

在这里测试。

说明

q~       e# Read and evaluate input.
{        e# Map this block over the list of presents...
  3*     e#   Repeat the list of lengths 3 times. This will expand cuboids to 9 elements
         e#   and spheres to three copies of the radius.
  )      e#   Pull off the last element.
  4P*3/* e#   Multiply by 4 pi / 3.
  +      e#   Add it back to the list of lengths.
  3<     e#   Truncate to 3 elements. This is a no-op for spheres, which now have three
         e#   elements [r r 4*pi/3*r] but discards everything we've done to cuboids, such
         e#   that they're reduced to their three side lengths again.
  :*     e#   Multiply the three numbers in the list.
}%
:+       e# Sum all the individual volumes.

2

PowerShell,67字节

($args|%{($_,((,$_*3)+4.18879))[$_.count-eq1]-join'*'})-join'+'|iex

这里发生了一些黑魔法。我会尝试顺利进行。

我们首先将我们的输入(期望作为单个逗号分隔的数组,例如)输入(1,4,3) (2,2,2) (3) (4,4,4)管道|%{}

在循环内部,我们首先检查$_我们正在考虑的特定数组是否只有一项,然后使用它来索引数组(本质上是一个较短的if / else构造)。如果它不止一项,则假设(1,4,3)我们作为输入来执行前一半,这只是通过吐出数组$_,例如(1,4,3)。否则,我们将创建一个新的动态数组,该数组由3个元素组成,(,$_*3)并以4 / 3rd * Pi近似固定。对于输入(3),这将导致(3,3,3,4.18879)输出。

是的,PowerShell有一个Pi常量,可以通过.NET调用进行访问[math]::PI,但这更长,而且我不想使用它。:p

无论如何,我们通过-join'*',so 将该输出数组与星号连接起来"1*4*3"。一旦我们完全完成了循环,便有了字符串的集合。我们将-join'+'所有这些加在一起,并iex使用表达式来计算结果。

ew


1

Ruby,58个字符

->b{b.reduce(0){|t,s|a,b,c=*s;t+(c ?a*b*c :a**3*4.18879)}}

样品运行:

2.1.5 :001 ->b{b.reduce(0){|t,s|a,b,c=*s;t+(c ?a*b*c :a**3*4.18879)}}[[[1,4,3],[2,2,2],[3],[4,4,4]]]
 => 197.09733

Ruby,50个字符

edc65JavaScript答案无耻地窃取了改进想法。

->b{t=0;b.map{|a,b,c|t+=c ?a*b*c :a**3*4.18879};t}

样品运行:

2.1.5 :001 > ->b{t=0;b.map{|a,b,c|t+=c ?a*b*c :a**3*4.18879};t}[[[1,4,3],[2,2,2],[3],[4,4,4]]]
 => 197.09733

1

Japt,27个 22字节

N®r*1 ª4/3*M.P*Zg ³} x

将输入作为以空格分隔的数组。在线尝试!

怎么运行的

N®   r*1 ª 4/3*M.P*Zg ³  } x
NmZ{Zr*1 ||4/3*M.P*Zg p3 } x

          // Implicit: N = array of input arrays
NmZ{   }  // Map each item Z in N to:
Zr*1      //  Reduce Z with multiplication.
||4/3*M.P //  If this is falsy, calculate 4/3 times Pi
*Zg p3    //  times the first item in Z to the 3rd power.
x         // Sum the result.
          // Implicit: output last expression


1

,23字节

{$*a|4/3*PI*@a**3}MSg^s

有两种方法可以为该程序提供输入。它可以将每个出席者作为三个三个以空格分隔的数字的命令行参数(需要将其用引号引起来:)pip.py present.pip "1 4 3" "3 0 0"。或者,指定-r标志并将每个存在的行作为标准输入行组成,该行由三个以空格分隔的数字组成。在线尝试!

怎么样?

                         g is list of cmdline args (or lines of stdin, if using -r flag)
                         s is space, PI is what it says on the tin (implicit)
                    g^s  Split each argument on spaces, so we have a list of lists
{                }MS     Map this function to each sublist and sum the results:
 $*a                      Fold the list on * (i.e. take the product)
    |                     Logical OR: if the above value is zero, use this value instead:
     4/3*PI*              4/3 pi, times
            @a            First element of the list
              **3         Cubed
                         Autoprint the result

0

Perl 5,142个字节

-p在命令行中运行with ,然后输入以逗号分隔的数字,如下所示:

5,0,0 要么 (5,0,0)

会产生

523.598820058997

没有 piPerl中关键字。在大多数情况下,这对于指定的有效数字是准确的,但是,即使我键入了我知道的pi的所有数字,对于某些计算也不是很准确。所以我留下来3.1415。我不确定这是否可以接受。

码:

@a=$_=~/(\d+,*)/g;$_=0;@n = map(split(/\D/),@a);for($i=0;$i<$#n;$i+=3){$x=$n[$i];$n[$i+1]==0?$_+=1420/339*$x**3:$_+=($x*$n[$i+1]*$n[$i+2]);}

根据丹尼斯(Dennis)的建议进行了编辑,以提高精度,丹尼斯在基础数学上比I更好,并且根据迈克尔·泰尔(MichaelT)的建议,在保留字节数的同时保持了精确度。


2
1.您将如何解析1511?2. 3.1415的舍入不正确也不足够精确。如果我的计算正确,则误差不得大于0.0000017。3. (4/3)*3.1415可以用单个浮子代替。
丹尼斯

1. OP表示我们可能假设球体的尾随零(实际上是我提供的示例输入),2。我不知道您使用的是什么计算,但是可以肯定的是,我会提高精度,以及3好建议,我错过了那个。谢谢!
Codefun64

我目前没有足够的资源,尽管我想知道这样做1420/339是否可以合理地逼近您。(这是4/3 * 355/113)。分数和您拥有的值之间的差是-8.49130615e-8

@MichaelT这是最有趣的事情。您是否有一个脚本可以找到最小的数字小数表示形式?;)
Codefun64

Codefun64我只是对pi 进行了其他通用近似处理。22/7的容忍度不足,因此我浏览了en.wikipedia.org/wiki/Approximations_of_%CF%80,然后使用下一个来查看其容忍度是否优于@Dennis的要求。

0

Lua中,115个 104字节

function f(a)b=0 for i=1,#a do c=a[i]b=b+(1<#c and c[1]*c[2]*c[3]or(4/3)*math.pi*c[1]^3)end return b end

简单的解决方案是,我必须将伪三元运算包装<condition> and <non-false> or <value if false>在括号中,否则b将同时包含两个区域。

输入必须采用以下形式,array={{1,4,3},{2,2,2},{3},{4,4,4}}并且可以通过执行查看结果print(f(array))


0

05AB1E18 16 字节

εDgi3m4žq*3/*]PO

在线尝试。

说明:

ε                # Map each inner list of the (implicit) input to:
 D               #  Duplicate the current inner list
  gi             #  Is the length 1 (is it an `R`):
    3m           #   Take the duplicated current item and take its cube
                 #    i.e. [3] → [27]
      žq         #   PI
        4*       #   Multiplied by 4
          3/     #   Divided by 3
                 #    → 4.1887902047863905
            *    #   And multiply it with the current cubed `R`
                 #    [27] and 4.1887902047863905 → [113.09733552923254]
]                # Close both the if and map
 P               # Take the product of each inner list
                 #  i.e. [[1,4,3],[2,2,2],[113.09733552923254],[4,4,4]]
                 #   → [12,8,113.09733552923254,64]
  O              # Take the total sum (and output implicitly)
                 #  i.e. [12,8,113.09733552923254,64] → 197.09733552923254

0

R,38 36字节

function(x,y=4*pi/3*x,z=x)sum(x*y*z)

使用默认参数在两种情况之间切换:使用三个参数计算乘积,使用一个参数计算球面公式。


您需要f<-{}吗?
朱塞佩

对于测试用例,此代码无法正确输出(5,0,0)。而且,它不能容纳有多个礼物并且需要将音量加在一起的测试用例。
罗伯特S.18年

对于(5,0,0)我得到零-这是不正确的?已编辑使用sum(根据Giuseppe的建议删除了一些不必要的东西)
JDL
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.