Berechnen Sie das Volumen eines Objekts

18

Sie können das Volumen von Objekten basierend auf einer bestimmten Menge von Dimensionen bestimmen:

  • Das Volumen einer Kugel kann mit einer einzigen Zahl, dem Radius ( r), bestimmt werden.
  • Das Volumen eines Zylinders kann mit zwei Zahlen bestimmt werden, dem Radius ( r) und der Höhe ( h).
  • Das Volumen einer Box kann anhand von drei Zahlen bestimmt werden, der Länge ( l), der Breite ( w) und der Höhe ( h).
  • Das Volumen einer unregelmäßigen dreieckigen Pyramide kann anhand von vier Zahlen, den Seitenlängen ( a, b, c) und der Höhe ( h) bestimmt werden.

Die Herausforderung besteht darin, das Volumen eines Objekts bei einer der folgenden Eingaben zu bestimmen:

  • Eine einzelne Zahl (r)oder (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Zwei Zahlen (r, h)oder (r, h, 0, 0)=>V = pi*r^2*h
  • Drei Zahlen (l, w, h)oder (l, w, h, 0)=>V = l*w*h
  • Vier Zahlen (a, b, c, h)=> V = (1/3)*A*h, wobei Adurch Herons Formel gegeben ist :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Regeln und Erläuterungen:

  • Die Eingabe kann sowohl Ganzzahlen als auch Dezimalzahlen sein
  • Sie können davon ausgehen, dass alle Eingabedimensionen positiv sind
  • Wenn Pi hart codiert ist , muss es genau bis zu: 3.14159.
  • Die Ausgabe muss aus mindestens 6 signifikanten Ziffern bestehen, mit Ausnahme von Zahlen, die mit weniger Ziffern genau dargestellt werden können. Sie können ausgeben 3/4als 0.75, 4/3müssen aber sein 1.33333(mehr Ziffern sind OK)
    • Das Runden von ungenauen Werten ist optional
  • Das Verhalten bei ungültiger Eingabe ist undefiniert
  • Standardregeln für E / A. Die Eingabe kann eine Liste oder separate Argumente sein

Dies ist Codegolf, daher gewinnt die kürzeste Lösung in Bytes.

Testfälle:

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

Verwandt, aber anders .

Stewie Griffin
quelle
1
Muss die Reihenfolge der Abmessungen der in der Frage angegebenen Reihenfolge entsprechen?
Mego
Related
Sp3000
@ Mego, können Sie wählen ...
Stewie Griffin
@StewieGriffin Varargs und das Erreichen von Arrays mit dynamischer Größe ist ein Problem in meiner Sprache (zumindest für mich Anfänger). Kann ich vier Funktionen bereitstellen, um jede Arg-Anzahl zu verarbeiten?
Katze
Sie können ein Array mit fester Größe haben, wobei die letzten Elemente bei Bedarf auf Null gesetzt werden. Das sollte es abdecken, denke ich? Oder Sie können Funktionen wie in der Haskell-Antwort überladen. Sie können keine unterschiedlichen Funktionen mit unterschiedlichen Namen haben.
Stewie Griffin

Antworten:

4

MATL , 57 53 51 44 Bytes

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

Die Eingabe ist ein Array mit 1, 2, 3 oder 4 Zahlen.

Probieren Sie es online!

Erläuterung

Anstatt verschachtelte ifSchleifen zu verwenden, die in Bezug auf Bytes teuer sind, werden vier mögliche Ergebnisse für jede Eingabe berechnet und dann das entsprechende Ergebnis in Abhängigkeit von der Eingabelänge ausgewählt.

Obwohl nur eines der Ergebnisse gültig sein muss, können die anderen bei der Berechnung keine Fehler melden. Dies bedeutet beispielsweise, dass die Indizierung des vierten Elements der Eingabe nicht zulässig ist, da die Eingabe möglicherweise weniger als vier Elemente enthält.

                    % 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
quelle
Welche Wiedergabe von Herons Formel verwenden Sie?
Addison Crump
@CoolestVeto Der mit dem Semiperimeter. Erste Formel von hier
Luis Mendo
Gut gemacht @DonMuesli. Ich schaffte es mit "nur" 34 Bytes mehr in MATLAB =)
Stewie Griffin
9

Vitsy, 49 Bytes

Ich dachte, Sie gaben mir dieses auf einem Teller, aber ich fand einen ungelösten Fehler, um das Problem zu umgehen. Hat mich aber nicht verletzt.

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

Da die Eingabe für verschiedene Funktionen eine bestimmte Länge hat, geben Sie mir meine Methodensyntax für diese Aufgaben an. Also ja, Erfolg!

Erläuterung zeilenweise:

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.

Eingaben werden genau umgekehrt wie in der Frage angegeben als Befehlszeilenargumente ohne nachfolgende Nullen akzeptiert.

Probieren Sie es online!

Nebenbei bemerkt, hier ist etwas, das sich derzeit in der Entwicklung befindet.

Java mit Vitsy-Paket

Beachten Sie, dass dieses Paket in Bearbeitung ist. Dies soll nur zeigen, wie dies in Zukunft funktionieren wird (Dokumentation hierfür ist noch nicht hochgeladen) und es wird nicht Golf gespielt und ist eine wörtliche Übersetzung:

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
quelle
1
Auf jeden Fall das richtige Werkzeug für den Job
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)

edit 1: entferne unnötige Nachkommastellen ., danke Immibis!

Josh
quelle
2
Kann nicht 4./3.einfach sein 4/3.? Und kann 2.und 12.ist 2und 12?
user253751
Sie sind absolut richtig. Vielen Dank!
Josh
4

JavaScript ES6, 129 126 125 116 114 90 Bytes

Dank Stewie Griffin konnten viele Bytes (9) mit einer wunderbaren Formel gespeichert werden! Da die Eingabe ungleich Null sein muss, variable?reicht dies für eine Definitionsprüfung aus.

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}

Probieren Sie es aus!

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
quelle
5
Mit Mathe? Klingt plausibel.
Addison Crump
Dieser Fehler auf Chrome 48, Uncaught SyntaxError: Unexpected token =(unter Bezugnahme auf Z=a*a)
Patrick Roberts
@PatrickRoberts Verwenden Sie Firefox. Es erlaubt Standardparameter innerhalb von Lambdas.
Conor O'Brien
Ich kann nicht scheinen, die 4-arg-Version zum Laufen zu bringen ... und Sie verwenden nie den Wert von h, der ein bisschen übersehen zu sein scheint.
Neil
@ Neil Huh, stimmt. Ich muss diese Formel noch einmal sehen, Stewie hat seinen Kommentar gelöscht ...
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)

Nimmt eine Liste von Zahlen und gibt ein Volumen zurück. Nenne es so

v[7]

für eine Kugel usw. Die Funktion ist polymorph für jeden Typ, der implementiert sqrt(also grundsätzlich Floatoder Double).

Es wird keine Wettbewerbe für die Kürze gewinnen. Beachten Sie jedoch, wie lesbar es ist. Auch wenn Sie Haskell nicht wirklich kennen, können Sie leicht sagen, was es tut. Mit der Pattern-Matching-Syntax von Haskell lassen sich auf einfache Weise seltsame Funktionen definieren, die je nach Form der Eingabe etwas völlig anderes bewirken.

MathematicalOrchid
quelle
1
(1/3)*(1/4)*h,,, warum nicht h/12? Spart Ihnen viele Bytes!
Stewie Griffin
1
Auch die Variante von Herons Equalizer, die Conor verwendet, scheint viel kürzer zu sein.
Stewie Griffin
@StewieGriffin Anscheinend ja. : -}
MathematicalOrchid
Haskell ist nur für Infix-Mathematik lesbar, was ich nicht lesbar finde. Dann steigen Sie in .und ein# und $und es wird Mathematica Soup.
Katze
3

PowerShell, 165 bis 161 Byte

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]

Also ... viele ... Dollar ... (31 der 161 Zeichen entsprechen $19,25% des Codes) ... aber dank Stewie Griffin wurden 4 Byte eingespart!

Wir nehmen vier Eingaben auf und indexieren sie dann schrittweise in pseudo-ternären Anweisungen in umgekehrter Reihenfolge. ZB (..., ...)[!$h]prüft die Außenseite , ob der vierte Eingang vorhanden ist. Wenn ja, ist der !$hWille gleich 0und die erste Hälfte wird ausgeführt (das Volumen einer unregelmäßigen dreieckigen Pyramide). Andernfalls wird !$hmit $h = $null(da es nicht initialisiert ist) gleich 1, so dass es zur zweiten Hälfte geht, die selbst ein Pseudoternär ist, basierend auf [!$c]und so weiter.

Dies ist wahrscheinlich nahezu optimal, da die angeblich kürzere Formel, die (z. B.) Cᴏɴᴏʀ O'Bʀɪᴇɴ verwendet, in PowerShell aufgrund des Fehlens von a tatsächlich 2 Byte länger ist^ Bedieners ... Die einzigen wirklichen Einsparungen kommen aus (1/3)*(1/4)*A*$hGolfen A*$h/12und Einstellung $pspäter, um ein paar Bytes anstelle des langwierigen [math]::PIAufrufs zu speichern .

AdmBorkBork
quelle
1

CJam, 67 66 Bytes

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

Ich werde bald daran arbeiten, es zu verkürzen. Probieren Sie es online !

Erklärung zu kommen.

GamrCorps
quelle
1

Im Ernst, 65 59 55 Bytes

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

Probieren Sie es online!

Erläuterung

Dieser ist ein Trottel. Ich werde die Erklärung in mehrere Teile aufteilen.

Hauptkörper:

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

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

Funktion 1:

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

Funktion 2:

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

Funktion 3 (21 Bytes; fast die Hälfte der Programmlänge!)

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

Sicher kann es nicht kürzer werden. ~b, ~cUnd ~dsind , 0wenn jede der Abmessungen ungleich Null ist. Eine Formel mit einer Nulldimension ergibt nur Null. Auf diese Weise kann jede der Formeln einfach summiert werden. Nein ifundelse erforderlich.

Nennen Sie es so (oder versuchen Sie es online hier ):

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
quelle
1
Was für ein Wahnsinn an Variablen :-) Ja, das scheint sich kaum weiter verkürzen zu lassen
Luis Mendo
Vielleicht einen Link hinzufügen, um es online auszuprobieren? ideone.com/6VZF9z
Luis Mendo
0

Python 3 2, 127 119 116 Bytes

Kredit jemand und Mego für alle ihre Hilfe bei Golf spielen. Wir danken auch Cᴏɴᴏʀ O'Bʀɪᴇɴ und Josh, als ich Teile ihrer Antworten für diese Frage ausgeliehen habe .

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]

Ungolfed:

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
quelle
Mehr Golf gespielt: 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]Vorausgesetzt, die Eingabe ist mit 0s aufgefüllt .
Nur ASCII
Wenn Sie stattdessen Python 2 verwenden, können Sie dies auch tundef 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)

Reine Funktion: 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&

Ungolfed:

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 &

Verwendung:

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

Wenn benannte Funktionen erlaubt sind: 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

Verwendung:

f[4]
268.083
f[5.5, 2.23]
211.924
f[3.5, 4, 5]
70.
f[4, 13, 15, 3]
24.
shrx
quelle
1
#1==#Ich denke Quiet[x_]:=Quiet[x,All]und π (Alt-P auf einem Mac) passt in erweitertes ASCII.
CalculatorFeline
Kannst du nicht ersetzen #1 #2 #3durch 1##? Vergiss nicht#==#1
CalculatorFeline
0

Faktor 783 Bytes

Nun, das hat ewig gedauert.

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 ;

Rufen Sie an { array of numbers } volume.

Katze
quelle
@StewieGriffin: PI hat völlig vergessen, die Namen der Funktionen zu kürzen. Wird aber nicht viel helfen.
Katze