Calcular el volumen de un objeto


18

Puede determinar el volumen de objetos en función de un conjunto dado de dimensiones:

  • El volumen de una esfera se puede determinar usando un solo número, el radio ( r)
  • El volumen de un cilindro se puede determinar usando dos números, el radio ( r) y la altura ( h)
  • El volumen de una caja se puede determinar usando tres números, la longitud ( l), el ancho ( w) y la altura ( h)
  • El volumen de una pirámide triangular irregular se puede determinar usando cuatro números, las longitudes laterales ( a, b, c) y la altura ( h).

El desafío es determinar el volumen de un objeto dada una de las siguientes entradas:

  • Un solo número (r)o (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Dos números (r, h)o (r, h, 0, 0)=>V = pi*r^2*h
  • Tres números (l, w, h)o (l, w, h, 0)=>V = l*w*h
  • Cuatro números (a, b, c, h)=> V = (1/3)*A*h, donde Aviene dado por la fórmula de Heron :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Reglas y aclaraciones:

  • La entrada puede ser tanto enteros como decimales
  • Puede asumir que todas las dimensiones de entrada serán positivas
  • Si Pi se codifica difícil que debe ser precisa hasta: 3.14159.
  • La salida debe tener al menos 6 dígitos significativos, excepto los números que se pueden representar con precisión con menos dígitos. Puede generar 3/4como 0.75, pero 4/3debe ser 1.33333(más dígitos están bien)
    • Cómo redondear valores inexactos es opcional
  • El comportamiento de la entrada no válida no está definido
  • Reglas estándar para E / S. La entrada puede ser una lista o argumentos separados

Este es el código de golf, por lo que gana la solución más corta en bytes.

Casos de prueba:

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

Relacionado, pero diferente .


1
¿Se requiere que el orden de las dimensiones sea el orden indicado en la pregunta?
Mego


@Mego, puedes elegir ...
Stewie Griffin

@StewieGriffin Varargs y llegar a matrices de tamaño dinámico es un dolor en mi lenguaje (al menos para mí, un principiante). ¿Puedo proporcionar cuatro funciones para manejar cada recuento de argumentos?
gato

Puede tener una matriz de tamaño fijo con los últimos elementos establecidos en cero si es necesario. Eso debería cubrirlo, creo? O puede sobrecargar funciones como en la respuesta de Haskell. No puede tener diferentes funciones con diferentes nombres.
Stewie Griffin

Respuestas:


4

MATL , 57 53 51 44 bytes

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

La entrada es una matriz con 1, 2, 3 o 4 números.

Pruébalo en línea!

Explicación

En lugar de usar ifbucles anidados , lo cual es costoso en términos de bytes, calcula cuatro resultados posibles para cualquier entrada y luego selecciona el resultado apropiado según la longitud de la entrada.

Al calcular los resultados, aunque solo uno de ellos debe ser válido, los otros no pueden dar errores. Esto significa, por ejemplo, que la indexación del cuarto elemento de la entrada no está permitida, porque la entrada puede tener menos de cuatro elementos.

                    % 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

¿Qué versión de la fórmula de Heron estás usando?
Addison Crump

@CoolestVeto El que tiene el semiperímetro. Primera fórmula desde aquí
Luis Mendo

Bien hecho @DonMuesli. Lo logré usando "solo" 34 bytes más en MATLAB =)
Stewie Griffin

9

Vitsy, 49 bytes

Pensé que me entregaste este en un plato, pero encontré un error sin resolver para solucionar. Sin embargo, no me hizo daño.

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

Básicamente, dado que la entrada tiene una cierta longitud para diferentes funciones, me das la sintaxis de mi método para hacer esto. Entonces, ¡éxito!

Explicación, una línea a la vez:

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.

La entrada se acepta como argumentos de línea de comando en el reverso exacto tal como aparecen en la pregunta, sin ceros finales.

Pruébalo en línea!

Como comentario, aquí hay algo que está actualmente en desarrollo.

Paquete Java con Vitsy

Tenga en cuenta que este paquete es un trabajo en progreso; esto es sólo para mostrar cómo va a funcionar en el futuro (documentación para esto todavía no se carga) y se no jugó golf, y es una traducción literal:

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
Definitivamente la herramienta adecuada para el trabajo
Mego

5

C, 100 97 bytes

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

editar 1: eliminar decimales innecesarios ., gracias Immibis!


2
No puede 4./3.ser solo 4/3.? ¿Y puede 2.y 12.solo ser 2y 12?
user253751

Tienes toda la razón. ¡Gracias!
Josh

4

JavaScript ES6, 129 126 125 116 114 90 bytes

¡Ahorré muchos bytes (9) con una fórmula maravillosa, gracias a Stewie Griffin! Como la entrada debe ser distinta de cero, variable?será suficiente para una verificación de definición.

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}

¡Pruébalo!

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>


55
Con las matematicas? Parece legitimo.
Addison Crump

Estos errores en Chrome 48, Uncaught SyntaxError: Unexpected token =(refiriéndose a Z=a*a)
Patrick Roberts

@PatrickRoberts Usa Firefox. Permite parámetros predeterminados dentro de lambdas.
Conor O'Brien

Parece que no puedo hacer que la versión de 4 argumentos funcione ... y nunca usas el valor de h, lo que parece un poco descuidado.
Neil

@Neil Huh, cierto. Necesito ver esa fórmula nuevamente, Stewie borró su comentario ...
Conor O'Brien

3

Haskell, 114 109 107 101 99 bytes

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)

Toma una lista de números y devuelve un volumen. Llámalo como

v[7]

para una esfera, etc. La función es polimórfica para cualquier tipo que implemente sqrt(básicamente, Floato Double).

No va a ganar ningún concurso por brevedad. Pero tenga en cuenta lo legible que es. Incluso si realmente no conoce a Haskell, puede decir lo que hace con bastante facilidad. La sintaxis de coincidencia de patrones de Haskell hace que sea realmente fácil definir funciones extrañas que hacen algo totalmente diferente dependiendo de la forma de la entrada.


1
(1/3)*(1/4)*h,,, por qué no h/12? ¡Te ahorra muchos bytes!
Stewie Griffin

1
Además, la variante del ecualizador de Heron que usa Conor parece ser mucho más corta.
Stewie Griffin

@StewieGriffin Aparentemente sí. : -}
MathematicalOrchid

Haskell solo es legible para matemática infija, que no encuentro legible. Luego de entrar en .y #y $y se convierte en sopa de Mathematica.
gato

3

PowerShell, 165 161 bytes

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]

Entonces ... Muchos ... Dólares ... (31 de los 161 caracteres son $, para el 19.25% del código) ... pero, ¡ahorraron 4 bytes gracias a Stewie Griffin!

Tomamos cuatro entradas y luego las indexamos progresivamente en declaraciones pseudoternarias basadas en ellas en orden inverso. Por ejemplo, el exterior (..., ...)[!$h]prueba si la cuarta entrada está presente. Si es así, la !$hvoluntad será igual 0y se ejecutará la primera mitad (el volumen de una pirámide triagonal irregular). De lo contrario, !$hcon $h = $null(ya que no está inicializado) será igual 1, por lo que pasa a la segunda mitad, que es un pseudoternario basado en [!$c]y así sucesivamente.

Es probable que esto sea casi óptimo, ya que la fórmula supuestamente más corta que (por ejemplo) Cᴏɴᴏʀ O'B is está usando es en realidad 2 bytes más larga en PowerShell gracias a la falta de un ^operador ... Los únicos ahorros reales provienen del (1/3)*(1/4)*A*$hgolf A*$h/12y configurando $pmás tarde para guardar un par de bytes en lugar de la larga [math]::PIllamada.


1

CJam, 67 66 bytes

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

Trabajaré para acortarlo pronto. Pruébalo en línea !

Explicación por venir.


1

En serio, 65 59 55 bytes

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

Pruébalo en línea!

Explicación

Este es un doozy. Voy a dividir la explicación en varias partes.

Cuerpo principal:

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

Función 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)

Función 1:

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

Función 2:

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

Función 3 (21 bytes; ¡casi la mitad de la longitud del programa!)

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 bytes

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

Muy seguro de que no puede ser más corto que esto. ~b, ~cy ~d, 0si cada una de las dimensiones no es cero. Una fórmula con una dimensión cero solo dará cero. De esa manera, cada una de las fórmulas puede simplemente sumarse. No ify elserequerido.

Llámalo así (o pruébalo en línea aquí ):

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
Qué locura de variables :-) Sí, esto parece difícil de acortar aún más
Luis Mendo

¿Quizás agregar un enlace para probarlo en línea? ideone.com/6VZF9z
Luis Mendo

0

Python 3 2, 127 119 116 bytes

Gracias a alguien y a Mego por toda su ayuda con el golf. También le doy crédito a Cᴏɴᴏʀ O'Bʀɪᴇɴ y Josh cuando tomé prestadas partes de sus respuestas para esta.

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]

Sin golf:

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]

Más golf: 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]asumiendo que la entrada está rellenada con 0s.
Solo ASCII

Además, si usa Python 2 en su lugar, puede hacerlodef 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]
solo ASCII

0

Mathematica, 114 (103)

Función pura: 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&

Sin golf:

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 &

Uso:

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

Si se permiten funciones con nombre: 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

Uso:

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==#, Creo Quiet[x_]:=Quiet[x,All]y π (Alt-P en una Mac) encaja en ASCII extendido.
CalculatorFeline

¿No puedes reemplazar #1 #2 #3con 1##? No lo olvides#==#1
CalculatorFeline

0

Factor, 783 bytes

Bueno, esto tomó una eternidad.

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 ;

Llamada { array of numbers } volume.


@StewieGriffin: PI olvidó por completo acortar los nombres de las funciones. Sin embargo, no ayudará mucho.
gato
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.