Calculer le volume d'un objet

18

Vous pouvez déterminer le volume d'objets en fonction d'un ensemble de dimensions donné:

  • Le volume d'une sphère peut être déterminé à l'aide d'un seul chiffre, le rayon ( r)
  • Le volume d'un cylindre peut être déterminé à l'aide de deux nombres, le rayon ( r) et la hauteur ( h)
  • Le volume d'une boîte peut être déterminé à l'aide de trois chiffres, la longueur ( l), la largeur ( w) et la hauteur ( h)
  • Le volume d'une pyramide triangulaire irrégulière peut être déterminé à l'aide de quatre nombres, les longueurs latérales ( a, b, c) et la hauteur ( h).

Le défi consiste à déterminer le volume d'un objet en fonction de l'une des entrées suivantes:

  • Un seul numéro (r)ou (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Deux chiffres (r, h)ou (r, h, 0, 0)=>V = pi*r^2*h
  • Trois chiffres (l, w, h)ou (l, w, h, 0)=>V = l*w*h
  • Quatre nombres (a, b, c, h)=> V = (1/3)*A*h, où Aest donné par la formule de Heron :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Règles et clarifications:

  • L'entrée peut être à la fois des entiers et / ou des décimales
  • Vous pouvez supposer que toutes les dimensions d'entrée seront positives
  • Si Pi est codé en dur , il doit être précis jusqu'à: 3.14159.
  • La sortie doit avoir au moins 6 chiffres significatifs, à l'exception des nombres qui peuvent être représentés avec précision avec moins de chiffres. Vous pouvez sortir en 3/4tant que 0.75, mais 4/3doit l'être 1.33333(plus de chiffres sont OK)
    • Comment arrondir des valeurs inexactes est facultatif
  • Le comportement pour une entrée non valide n'est pas défini
  • Règles standard pour les E / S. L'entrée peut être une liste ou des arguments séparés

C'est le golf de code, donc la solution la plus courte en octets gagne.

Cas de test:

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

Lié, mais différent .

Stewie Griffin
la source
1
L'ordre des dimensions doit-il être celui indiqué dans la question?
Mego
En relation
Sp3000
@Mego, vous pouvez choisir ...
Stewie Griffin
@StewieGriffin Varargs et obtenir des tableaux de taille dynamique est une douleur dans ma langue (au moins pour moi, un débutant dans ce domaine). Puis-je fournir quatre fonctions pour gérer chaque nombre d'arguments?
cat
Vous pouvez avoir un tableau de taille fixe avec les derniers éléments mis à zéro si besoin est. Cela devrait le couvrir, je pense? Ou vous pouvez surcharger les fonctions comme dans la réponse Haskell. Vous ne pouvez pas avoir différentes fonctions avec des noms différents.
Stewie Griffin

Réponses:

4

MATL , 57 53 51 44 octets

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

L'entrée est un tableau avec 1, 2, 3 ou 4 chiffres.

Essayez-le en ligne!

Explication

Au lieu d'utiliser des ifboucles imbriquées , ce qui coûte cher en octets, cela calcule quatre résultats possibles pour n'importe quelle entrée, puis sélectionne le résultat approprié en fonction de la longueur de l'entrée.

Lors du calcul des résultats, même si un seul doit être valide, les autres ne peuvent pas donner d'erreurs. Cela signifie par exemple que l'indexation du quatrième élément de l'entrée n'est pas autorisée, car l'entrée peut avoir moins de quatre éléments.

                    % 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
Luis Mendo
la source
Quelle interprétation de la formule de Heron utilisez-vous?
Addison Crump
@CoolestVeto Celui avec le semi-périmètre. Première formule d' ici
Luis Mendo
Bravo @DonMuesli. Je l'ai réussi en utilisant "seulement" 34 octets de plus dans MATLAB =)
Stewie Griffin
9

Vitsy, 49 octets

Je pensais que vous m'aviez remis celui-ci sur une assiette, mais j'ai trouvé un bug non résolu pour contourner. Mais ça ne m'a pas fait de mal.

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

Fondamentalement, l'entrée étant d'une certaine longueur pour différentes fonctions, vous me fournissez ma syntaxe de méthode pour faire ce genre de choses. Alors, oui, succès!

Explication, une ligne à la fois:

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.

L'entrée est acceptée en tant qu'arguments de ligne de commande dans le sens inverse exact, tels qu'ils apparaissent dans la question, sans zéros de fin.

Essayez-le en ligne!

En passant, voici quelque chose qui est actuellement en développement.

Java avec package Vitsy

Notez que ce package est en cours de réalisation; c'est juste pour montrer comment cela fonctionnera à l'avenir (la documentation n'est pas encore téléchargée) et ce n'est pas joué, et c'est une traduction littérale:

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)));
    }
}
Addison Crump
la source
1
Certainement le bon outil pour le travail
Mego
5

C, 100 97 octets

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

modifier 1: supprimez les décimales inutiles ., merci Immibis!

Josh
la source
2
Tu ne peux pas 4./3.l'être 4/3.? Et peut 2.et 12.simplement être 2et 12?
user253751
Vous avez tout à fait raison. Merci!
Josh
4

JavaScript ES6, 129 126 125 116 114 90 octets

Beaucoup d'octets enregistrés (9) avec une merveilleuse formule, grâce à Stewie Griffin! Puisque l'entrée doit être différente de zéro, variable?suffira pour une vérification de définition.

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}

Testez-le!

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>

Conor O'Brien
la source
5
Avec les mathématiques? Semble légitime.
Addison Crump
Cette erreur sur Chrome 48, Uncaught SyntaxError: Unexpected token =(se référant à Z=a*a)
Patrick Roberts
@PatrickRoberts Utilisez Firefox. Il permet des paramètres par défaut à l'intérieur de lambdas.
Conor O'Brien
Je n'arrive pas à faire fonctionner la version à 4 arguments ... et vous n'utilisez jamais la valeur de h, ce qui semble un peu un oubli.
Neil
@Neil Huh, c'est vrai. Je vais avoir besoin de revoir cette formule, Stewie a supprimé son commentaire ...
Conor O'Brien
3

Haskell, 114 109 107 101 101 99 octets

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)

Prend une liste de nombres et renvoie un volume. Appelez ça comme

v[7]

pour une sphère, etc. La fonction est polymorphe pour tout type qui implémente sqrt(donc, fondamentalement Floatou Double).

Cela ne va pas gagner de concours pour la brièveté. Mais notez à quel point c'est lisible . Même si vous ne connaissez pas vraiment Haskell, vous pouvez dire ce qu'il fait assez facilement. La syntaxe de correspondance de motifs de Haskell facilite la définition de fonctions étranges qui font quelque chose de totalement différent selon la forme de l'entrée.

MathematicalOrchid
la source
1
(1/3)*(1/4)*h,,, pourquoi pas h/12? Vous fait économiser beaucoup d'octets!
Stewie Griffin
1
De plus, la variante de l'égalisation de Heron que Conor utilise semble être beaucoup plus courte.
Stewie Griffin
@StewieGriffin Apparemment oui. : -}
MathematicalOrchid
Haskell n'est lisible que pour les mathématiques infixes, ce que je ne trouve pas lisible. Ensuite , vous entrez dans .et #et $et il devient Mathematica soupe.
cat
3

PowerShell, 165 161 octets

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]

Donc ... Beaucoup ... Dollars ... (31 des 161 caractères sont $, pour 19,25% du code) ... mais, économisés 4 octets grâce à Stewie Griffin!

Nous prenons quatre entrées, puis nous indexons progressivement en déclarations pseudo-ternaires basées sur celles-ci dans l'ordre inverse. Par exemple, l'extérieur (..., ...)[!$h]teste si la quatrième entrée est présente. Si c'est le cas, la !$hvolonté sera égale 0et la première moitié sera exécutée (le volume d'une pyramide triagonale irrégulière). Sinon, !$havec $h = $null(car il n'est pas initialisé) sera égal 1, il passe donc à la seconde moitié, qui est elle-même un pseudo-ternaire basé sur [!$c]et ainsi de suite.

Ceci est probablement presque optimal, car la formule soi-disant plus courte que (par exemple) Cᴏɴᴏʀ O'Bʀɪᴇɴ utilise est en fait 2 octets de plus dans PowerShell grâce au manque d' ^opérateur ... Les seules économies réelles proviennent du (1/3)*(1/4)*A*$hgolf vers A*$h/12, et définissant $pplus tard pour enregistrer quelques octets au lieu de l' [math]::PIappel long .

AdmBorkBork
la source
1

CJam, 67 66 octets

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

Je vais travailler sur le raccourcir bientôt. Essayez-le en ligne !

Explication à venir.

GamrCorps
la source
1

Sérieusement, 65 59 55 octets

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

Essayez-le en ligne!

Explication

Celui-ci est un doozy. Je vais diviser l'explication en plusieurs parties.

Corps 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

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

Fonction 1:

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

Fonction 2:

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

Fonction 3 (21 octets; près de la moitié de la durée du programme!)

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)
Mego
la source
1

Matlab, 78 octets

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

Bien sûr, il ne peut pas être plus court que cela. ~b, ~cet ~d, le sont 0si chacune des dimensions est différente de zéro. Une formule avec une dimension nulle donnera simplement zéro. De cette façon, chacune des formules peut simplement être additionnée. Non ifet elseobligatoire.

Appelez-le comme ça (ou essayez-le en ligne ici ):

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
Stewie Griffin
la source
1
Quelle folie des variables :-) Oui, cela semble difficile à raccourcir davantage
Luis Mendo
Peut-être ajouter un lien pour l'essayer en ligne? ideone.com/6VZF9z
Luis Mendo
0

Python 3 2, 127 119 119 116 octets

Crédit à quelqu'un et Mego pour leur aide avec le golf. Nous remercions également Cᴏɴᴏʀ O'Bʀɪᴇɴ et Josh car j'ai emprunté une partie de leurs réponses pour celle-ci.

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]

Non 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]
Sherlock9
la source
Golfed more:, en 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]supposant que l'entrée est complétée par l' 0art.
ASCII uniquement
De plus, si vous utilisez Python 2 à la place, vous pouvez le fairedef 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 uniquement
0

Mathematica, 114 (103)

Fonction pure: 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&

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

Usage:

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

Si les fonctions nommées sont autorisées: 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

Usage:

f[4]
268.083
f[5.5, 2.23]
211.924
f[3.5, 4, 5]
70.
f[4, 13, 15, 3]
24.
shrx
la source
1
#1==#, Je pense Quiet[x_]:=Quiet[x,All]et π (Alt-P sur un Mac) tient en ASCII étendu.
CalculatorFeline
Vous ne pouvez pas remplacer #1 #2 #3par 1##? N'oubliez pas#==#1
CalculatorFeline
0

Facteur, 783 octets

Eh bien, cela a pris une éternité.

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 ;

Appelle { array of numbers } volume.

chat
la source
@StewieGriffin: PI a totalement oublié de raccourcir les noms des fonctions. N'aidera pas beaucoup, cependant.
cat