Quanto presente você ganhou no Natal?

32

Sim, como muito , não quantas ...

Como todos sabemos, um presente grande é muito melhor que um pequeno. Portanto, o valor dos presentes sempre deve ser medido em volume total, não em número de presentes, peso ou mesmo preço combinado.

Como é desajeitado comparar a quantidade de presentes que se recebe, você não quer um longo script que seja facilmente visto e lido por outras pessoas na festa de Natal. Portanto, você precisa manter o número de bytes em seu script no mínimo.

Sua tarefa é simples: crie um programa que obtenha uma lista de dimensões como entrada, em qualquer formato adequado, e produz o volume combinado de seus presentes. A dimensão de cada presente será um conjunto de três números ou um único número. Se a entrada tiver três números ( L, W, H), o presente será um cubo de dimensões L x W x H. Se for um número único ( R), o presente é uma esfera de raio R.

Regras:

  • Pode ser um programa completo ou uma função
  • A entrada pode estar em qualquer formato conveniente
    • Se desejável, uma esfera pode ser representada por um número seguido por dois zeros
    • Um cubóide sempre terá todas as dimensões diferentes de zero.
  • A saída deve ser um único número decimal
    • Saída adicional é aceita, desde que seja óbvio qual é a resposta
    • A saída deve ter pelo menos dois dígitos após o ponto decimal
    • A saída pode estar na forma padrão / notação científica se o número for maior que 1000.
    • Caso seu idioma não tenha uma constante Pi, a resposta deve ser precisa até 9999,99.

Exemplos:

((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

Entre os melhores

O snippet de pilha na parte inferior desta postagem gera o catálogo a partir das respostas a) como uma lista da solução mais curta por idioma eb) como uma tabela geral de líderes.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

## Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

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

Você também pode transformar o nome do idioma em um link que será exibido no snippet:

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

Stewie Griffin
fonte
3
Nenhuma senhora usa chapéu em uma daquelas caixas cilíndricas engraçadas ?
manatwork
2
@manatwork, não, todas as senhoras terá chapéus-coco, e você pode facilmente se encaixam aqueles em uma esfera = P
Stewie Griffin
11
Eu suponho que (5)é apenas um exemplo parcial e nosso código só precisa lidar ((5)).
manatwork
2
Se nossa linguagem de escolha não possui uma constante Pi, quanta precisão é necessária?
Dennis
11
@manatwork, + e * são válidos desde que não signifiquem adição e multiplicação (ou outras operações) no idioma que você está usando.
Stewie Griffin

Respostas:

10

Geléia , 19 18 bytes

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

Experimente online!

Infelizmente, o Jelly ainda não possui uma constante π , e o vetorizador não manipula os flutuadores corretamente.

Para superar esses problemas, em vez de multiplicar por 4π / 3 , multiplicamos por 1420 e dividimos por 339 . Como 1420 ÷ 339 = 4,18879056… e 4π / 3 = 4,18879020… , isso é suficientemente preciso para cumprir as regras.

A versão mais recente do Jelly poderia realizar essa tarefa em 14 bytes , com melhor precisão.

Zµ*3×240°Ḣo@PS

Experimente online!

Como funciona

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.

A versão não concorrente usa em ×240°vez de ×1420÷339, que multiplica por 240 e converte os produtos em radianos.

Dennis
fonte
9

Haskell, 40 bytes

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

Exemplo de uso: sum.map q $ [[1,4,3],[2,2,2],[3],[4,4,4]]-> 197.09733552923254.

Como funciona: Para cada elemento da lista de entrada: se ele tiver um único elemento, xcalcule o volume da esfera, então pegue o product. Resumir.

nimi
fonte
11
Essa maneira de contar bytes geralmente é válida? Eu teria dito p=sum.map q(e, em seguida, disse para uso pem uma lista de listas de números)
Leif Willerts
11
@ LeifWillerts: Há um tópico recente sobre meta que permite funções sem nome que dependem de definições globais. sum.map qé uma função sem nome que depende q, então eu acho que está bem.
nimi
9

Pitão, 19 18 bytes

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

1 byte graças a Dennis

Demonstração

O formato de entrada é uma lista de listas:

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

Simplesmente multiplica as dimensões para calcular o volume do cubo. Se isso der zero, calcula o volume da esfera.

A constante da esfera 4/3*pié calculada como 240 graus em radianos. .t ... 7converte uma entrada em graus em radianos e C\ðcalcula o ponto de código de ð, que é 240.

isaacg
fonte
7

Python 2, 86 70 bytes

lambda i:sum(x[0]*x[1]*x[2]if len(x)>1 else x[0]**3*4.18879for x in i)
TFeld
fonte
Recebo sua contagem de bytes como 86, como você conseguiu a sua?
wnnmaw
Além disso, você pode salvar bytes 3.14159265358979323
digitando
@wnnmaw eu esqueci de contar a importação -.-
TFeld
Eu acredito que o seu valor codificado para pi é um off pouco :)
wnnmaw
4
@wnnmaw Isso não é Pi; é 4Pi / 3.
Dennis
5

Mathematica, 34 bytes

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

Uma função sem nome que pega uma lista aninhada de comprimentos e retorna o volume como um número real.

Primeiro, substituímos valores únicos pelo volume da esfera correspondente por /.{r_}:>{4r^3/3Pi}. Em seguida, multiplicamos o conteúdo de cada lista com 1.##&@@@. Finalmente, calculamos a soma como o traço do vetor com Tr[...].

Martin Ender
fonte
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

A versão mais sensata .reduce é 1 byte mais

l=>l.reduce((t,[x,y,z])=>t+(y?x*y*z:x*x*x*4/3*Math.PI),0)
edc65
fonte
Você pode salvar alguns bytes usando 4.11879no lugar de 4/3*Math.PI, pois isso deve ser preciso o suficiente para se qualificar.
ETHproductions
@ETHproductions sim, mas In case your language doesn't have a Pi-constant,e minha língua tem uma constante PI, então eu não sei se ela se qualifica
edc65
5

Python, 49 bytes

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

Usa a representação de esferas como (a,0,0). Tratado como um cuboide, ele possui o volume 0; nesse caso, o volume da esfera é usado. Não sei ao certo quão precisa é a constante, por isso espero que isso seja suficiente.

xnor
fonte
4

MATL , 20 bytes

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

O formato de entrada é uma matriz na qual cada linha descreve um cubo ou uma esfera. Uma esfera é definida apenas pelo primeiro número nessa linha; os outros dois números são zero. Portanto, o primeiro exemplo do desafio seria:

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

Isso usa a versão atual do idioma, 2.0.2 , que é anterior a esse desafio.

Exemplos:

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

Explicação:

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                
Luis Mendo
fonte
3

Prolog, 115 100 bytes

Código:

[]*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).

Explicado:

[]*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

Exemplos:

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

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

Experimente online aqui

Editar: salvou 15 bytes, definindo um predicado diádico.

Emigna
fonte
3

Perl, 52 47 bytes

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

46 + 1 para -p(isso tem sido comum; deixe-me saber se é diferente aqui e eu atualizarei)

Uso: coloque em um arquivo e echo 1,4,3 2,2,2 3 4,4,4 | perl -p x.pl

Com comentários:

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 $_

atualização 47 Obrigado a @Dennis por salvar alguns bytes usando este truque .

Kenney
fonte
s/,/*/g||s@$@**3*4.18879@,$\+=eval for/\S+/g;}{salva alguns bytes.
Dennis
@Dennis Thanks! Eu tentei com $ \ antes, mas redefinindo o $_custo tanto. Ainda não está claro por que $_é redefinido em um novo bloco. O $_local do bloco está ativado while(<>){}?
19415 Kenney
Sim, $_é a variável padrão do escopo atual. No bloco END, é indefinido.
Dennis
2

CJam, 24 21 bytes

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

Teste aqui.

Explicação

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.
Martin Ender
fonte
2

PowerShell, 67 bytes

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

Alguma magia negra acontecendo aqui. Vou tentar passar por isso sem problemas.

Primeiro, pegamos nossa entrada, esperada como matrizes individuais separadas por vírgula (1,4,3) (2,2,2) (3) (4,4,4), por exemplo , e colocamos isso em um loop |%{}.

Dentro do loop, primeiro verificamos se $_, a matriz em particular que estamos considerando, possui apenas um item e a usamos para indexar em uma matriz (essencialmente uma construção if / else mais curta). Se houver mais de um item, suponha (1,4,3)como entrada, executamos a primeira metade, que é simplesmente cuspir a matriz via $_, como (1,4,3). Caso contrário, criamos uma nova matriz dinâmica que consiste no elemento três vezes com (,$_*3)e aproximamos uma aproximação de 4 / 3rd * Pi. Para entrada (3), isso resultará em (3,3,3,4.18879)saída.

Sim, o PowerShell tem uma constante Pi, acessada via chamada .NET [math]::PI, mas é mais longa e não quero usá-la. : p

Independentemente disso, concatenamos essa matriz de saída com asteriscos via -join'*', então "1*4*3". Depois que passamos completamente pelo loop, agora temos uma coleção de strings. Todos nós -join'+'juntos para nossa adição e iexa expressão para calcular o resultado.

Ufa.

AdmBorkBork
fonte
1

Ruby, 58 caracteres

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

Exemplo de execução:

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 caracteres

Ideia melhoria descaradamente roubado de edc65 's resposta JavaScript .

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

Exemplo de execução:

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
homem a trabalhar
fonte
1

Japonês, 27 22 bytes

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

Recebe entrada como matrizes separadas por espaço. Experimente online!

Como funciona

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
ETHproductions
fonte
1

Pip , 23 bytes

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

Existem algumas maneiras de dar entrada neste programa. Pode levar cada presente como um argumento da linha de comando de três números separados por espaço (que precisarão ser colocados entre aspas:) pip.py present.pip "1 4 3" "3 0 0". Como alternativa, especifique o -rsinalizador e dê a cada presente como uma linha de stdin composta por três números separados por espaço. Experimente online!

Quão?

                         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
DLosc
fonte
0

Perl 5, 142 bytes

Execute -pna linha de comando e digite os números delimitados por vírgula, assim:

5,0,0 ou (5,0,0)

produziria

523.598820058997

Não há pipalavras-chave no Perl. Isso é, na maioria dos casos, preciso para os números significativos especificados, no entanto, mesmo se eu digitar todos os números de pi que eu conheço, não seria muito preciso para alguns cálculos. Então eu deixei com 3.1415. Não tenho certeza se isso é aceitável ou não.

Código:

@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]);}

Editado para maior precisão, seguindo o conselho de Dennis, que é melhor em matemática básica do que eu, e de uma sugestão de MichaelT para salvar bytes, mantendo-se preciso.

Codefun64
fonte
2
1. Como você analisaria 1511? 2. 3.1415 não é arredondado de forma adequada nem suficientemente precisa. Se meus cálculos estiverem corretos, o erro não deve ser maior que 0,0000017 . 3. (4/3)*3.1415pode ser substituído por um único flutuador.
Dennis
1. O OP diz que podemos assumir zeros à direita para as esferas (que é de fato a entrada de exemplo que forneci), 2. Não sei quais cálculos você está usando, mas com certeza aumentarei a precisão e 3 boa sugestão, eu perdi essa. Obrigado!
Codefun64
No momento, não tenho os recursos à minha frente, mas me pergunto se isso 1420/339lhe daria alguns bytes de volta com uma aproximação razoável. (este é 4/3 * 355/113). A diferença entre a fração e o valor que você tem é -8.49130615e-8 #
@ MichaelT Essa é a coisa mais interessante. Você tem um script que encontra a menor representação fracionária de números? ;)
Codefun64
Codefun64 Acabei de trabalhar com a outra aproximação comum para pi. 22/7 não tem tolerância suficiente, então olhei para en.wikipedia.org/wiki/Approximations_of_%CF%80 e usei o próximo para ver se ele tinha uma tolerância melhor do que o que @Dennis estava pedindo.
0

Lua, 115 104 bytes

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

Solução direta, eu tenho que envolver a operação pseudo-ternária <condition> and <non-false> or <value if false>entre parênteses, caso contrário b somaria com ambas as áreas.

A entrada deve estar no formato array={{1,4,3},{2,2,2},{3},{4,4,4}}e o resultado pode ser visto executando print(f(array)).

Katenkyo
fonte
0

05AB1E , 18 16 bytes

εDgi3m4žq*3/*]PO

Experimente online.

Explicação:

ε                # 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
Kevin Cruijssen
fonte
0

R, 38 36 bytes

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

Usa argumentos padrão para alternar entre os casos: com três argumentos calcula o produto e com um argumento calcula a fórmula da esfera.

JDL
fonte
você precisa do f<-e do {}?
Giuseppe
Este código não é gerado corretamente para o caso de teste (5,0,0). Além disso, ele não acomoda o caso de teste em que há vários presentes e os volumes precisam ser somados.
Robert S.
Pois (5,0,0) eu recebo zero - isso não está correto? Ter editado para uso sum(e removido algumas coisas que não era necessário por sugestão de Giuseppe)
JDL