Oblicz objętość obiektu


18

Możesz określić objętość obiektów na podstawie danego zestawu wymiarów:

  • Objętość kuli można określić za pomocą pojedynczej liczby, promienia ( r)
  • Objętość cylindra można określić za pomocą dwóch liczb, promienia ( r) i wysokości ( h)
  • Objętość pudełka można określić za pomocą trzech liczb, długości ( l), szerokości ( w) i wysokości ( h)
  • Objętość nieregularnej trójkątnej piramidy można określić za pomocą czterech liczb, długości boków ( a, b, c) i wysokości ( h).

Wyzwanie polega na określeniu objętości obiektu na podstawie jednego z następujących danych wejściowych:

  • Pojedyncza liczba (r)lub (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Dwie liczby (r, h)lub (r, h, 0, 0)=>V = pi*r^2*h
  • Trzy liczby (l, w, h)lub (l, w, h, 0)=>V = l*w*h
  • Cztery liczby (a, b, c, h)=> V = (1/3)*A*h, gdzie Apodana jest formuła Herona :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Zasady i wyjaśnienia:

  • Dane wejściowe mogą być zarówno liczbami całkowitymi, jak i dziesiętnymi
  • Możesz założyć, że wszystkie wymiary wejściowe będą dodatnie
  • Jeśli Pi jest zakodowana musi być dokładna do: 3.14159.
  • Dane wyjściowe muszą mieć co najmniej 6 cyfr znaczących, z wyjątkiem liczb, które można dokładnie przedstawić za pomocą mniejszej liczby cyfr. Możesz wyprowadzać 3/4jako 0.75, ale 4/3musi być 1.33333(więcej cyfr jest w porządku)
    • Sposób zaokrąglania niedokładnych wartości jest opcjonalny
  • Zachowanie nieprawidłowych danych wejściowych jest niezdefiniowane
  • Standardowe reguły we / wy. Dane wejściowe mogą być listą lub osobnymi argumentami

To jest kod golfowy, więc wygrywa najkrótsze rozwiązanie w bajtach.

Przypadki testowe:

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

Powiązane, ale różne .


1
Czy kolejność wymiarów musi być zgodna z kolejnością podaną w pytaniu?
Mego


@Mego, możesz wybrać ...
Stewie Griffin

@StewieGriffin Varargs i wchodzenie w dynamiczne tablice to ból w moim języku (przynajmniej dla mnie, początkujący). Czy mogę podać cztery funkcje do obsługi każdej liczby arg?
kot

W razie potrzeby możesz mieć tablicę o stałym rozmiarze z ostatnimi elementami ustawionymi na zero. Myślę, że to powinno to obejmować? Lub możesz przeciążać funkcje jak w odpowiedzi Haskell. Nie możesz mieć różnych funkcji o różnych nazwach.
Stewie Griffin

Odpowiedzi:


4

MATL , 57 53 51 44 bajtów

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

Dane wejściowe to tablica z 1, 2, 3 lub 4 cyframi.

Wypróbuj online!

Wyjaśnienie

Zamiast używać zagnieżdżonych ifpętli, co jest kosztowne pod względem bajtów, oblicza cztery możliwe wyniki dla dowolnego wejścia, a następnie wybiera odpowiedni wynik w zależności od długości wejścia.

Podczas obliczania wyników, chociaż tylko jeden z nich musi być poprawny, inne nie mogą dawać błędów. Oznacza to na przykład, że indeksowanie czwartego elementu danych wejściowych jest niedozwolone, ponieważ dane wejściowe mogą zawierać mniej niż cztery elementy.

                    % 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

Jakiej wersji formuły Heron używasz?
Addison Crump,

@CoolestVeto Ten z semipimetrem. Pierwsza formuła stąd
Luis Mendo

Dobra robota @DonMuesli. Udało mi się to, używając „tylko” 34 bajtów więcej w MATLAB =)
Stewie Griffin

9

Vitsy, 49 bajtów

Myślałem, że podałeś mi ten na talerzu, ale znalazłem nierozwiązany błąd do obejścia. Jednak mnie nie skrzywdziło.

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

Zasadniczo, ponieważ dane wejściowe mają określoną długość dla różnych funkcji, podajesz mi łyżkę składni mojej metody do robienia tych rzeczy. Tak, sukces!

Objaśnienie, jedna linia na raz:

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.

Dane wejściowe są akceptowane jako argumenty wiersza poleceń w dokładnie odwrotnej kolejności, w jakiej pojawiają się w pytaniu, bez zer końcowych.

Wypróbuj online!

Nawiasem mówiąc, oto coś, co jest obecnie w fazie rozwoju.

Java z pakietem Vitsy

Pamiętaj, że ten pakiet jest w toku; to jest po prostu pokazać, jak to będzie działać w przyszłości (dokumentacja ta nie jest jeszcze załadowane) i to nie grałem, i to dosłowne tłumaczenie:

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
Zdecydowanie właściwe narzędzie do pracy
Mego

5

C, 100 97 bajtów

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

edycja 1: usuń niepotrzebne dziesiętne ., dzięki Immibis!


2
Nie może 4./3.być po prostu 4/3.? A może 2.i 12.po prostu być 2i 12?
user253751,

Masz absolutną rację. Dzięki!
Josh

4

JavaScript ES6, 129 126 125 116 114 90 bajtów

Zaoszczędź dużo bajtów (9) dzięki wspaniałej formule, dzięki Stewie Griffin! Ponieważ dane wejściowe muszą być niezerowe, variable?wystarczą do sprawdzenia definicji.

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}

Przetestuj to!

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>


5
Z matematyką? Wydaje się legit.
Addison Crump

Te błędy w Chrome 48, Uncaught SyntaxError: Unexpected token =(odnosząc się do Z=a*a)
Patrick Roberts

@PatrickRoberts Użyj Firefox. Pozwala na domyślne parametry w lambdach.
Conor O'Brien,

Wydaje mi się, że nie mogę uruchomić wersji z 4 argumentami ... i nigdy nie używasz wartości h, co wydaje się trochę przeoczone.
Neil

@Neil Huh, prawda. Muszę zobaczyć tę formułę jeszcze raz, Stewie usunął swój komentarz ...
Conor O'Brien

3

Haskell, 114 109 107 101 99 bajtów

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)

Pobiera listę liczb i zwraca wolumin. Nazwij to jak

v[7]

dla kuli itp. Funkcja jest polimorficzna dla każdego typu, który implementuje sqrt(tak, w zasadzie Floatlub Double).

Nie wygra żadnych konkursów na zwięzłość. Ale zauważ, jak to jest czytelne . Nawet jeśli tak naprawdę nie znasz Haskell, możesz łatwo stwierdzić, co on robi. Składnia dopasowywania wzorców Haskella sprawia, że ​​bardzo łatwo jest zdefiniować dziwne funkcje, które robią coś zupełnie innego w zależności od kształtu wejścia.


1
(1/3)*(1/4)*h,,, dlaczego nie h/12? Oszczędza dużo bajtów!
Stewie Griffin

1
Także wariant eq Herona, z którego korzysta Conor, wydaje się znacznie krótszy.
Stewie Griffin

@StewieGriffin Najwyraźniej tak. : -}
MathematicalOrchid

Haskell jest czytelny tylko dla matematyki infiksów, których nie uważam za czytelne. Następnie pojawi się w .i #a $i staje Mathematica zupy.
kot

3

PowerShell, 165 161 bajtów

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]

Więc ... Wiele ... Dolarów ... (31 ze 161 znaków $, za 19,25% kodu) ... ale zaoszczędzono 4 bajty dzięki Stewie Griffin!

Pobieramy cztery dane wejściowe, a następnie stopniowo indeksujemy na podstawie pseudo-trójskładnikowych instrukcji na ich podstawie w odwrotnej kolejności. Np. Zewnętrzny (..., ...)[!$h]sprawdza, czy czwarty sygnał wejściowy jest obecny. Jeśli tak, test !$hbędzie równy, 0a pierwsza połowa zostanie wykonana (objętość nieregularnej piramidy trójkątnej). W przeciwnym razie, !$hz $h = $null(ponieważ jest niezainicjowany) będzie równy 1, więc przejdzie do drugiej połowy, która sama w sobie jest pseudo-trójką opartą na [!$c]i tak dalej.

Jest to prawdopodobnie zbliżone do optymalnego, ponieważ przypuszczalnie krótsza formuła, którą stosuje (np.) Cᴏɴᴏʀ O'Bʀɪᴇɴ, jest w rzeczywistości o 2 bajty dłuższa w PowerShell dzięki brakowi ^operatora ... Jedyne prawdziwe oszczędności pochodzą z (1/3)*(1/4)*A*$hgry w golfa A*$h/12i ustawienie $ppóźniej, aby zapisać kilka bajtów zamiast długiego [math]::PIpołączenia.


1

CJam, 67 66 bajtów

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

Niedługo będę pracował nad jego skróceniem. Wypróbuj online !

Wyjaśnienie, które nastąpi.


1

Poważnie, 65 59 55 bajtów

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

Wypróbuj online!

Wyjaśnienie

Ten jest doozy. Wytłumaczę to na kilka części.

Główny korpus:

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

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

Funkcja 1:

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

Funkcja 2:

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

Funkcja 3 (21 bajtów; prawie połowa długości programu!)

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 bajtów

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

Z całą pewnością nie może być krótszy niż ten. ~b, ~ci ~d, 0jeśli każdy z wymiarów jest niezerowy. Formuła o zerowym wymiarze da po prostu zero. W ten sposób każdą z formuł można po prostu zsumować. Nie ifielse wymagane.

Nazwij to tak (lub wypróbuj online tutaj ):

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
Co za szaleństwo zmiennych :-) Tak, to wydaje się trudne do dalszego skrócenia
Luis Mendo

Może dodaj link, aby wypróbować online? ideone.com/6VZF9z
Luis Mendo

0

Python 3 2, 127 119 116 bajtów

Kredyt na kogoś i Mego za ich pomoc w golfa. Podziękowania należą się również Cᴏɴᴏʀ O'B J i Joshowi, gdy pożyczyłem części ich odpowiedzi na tę jedną.

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]

Nie golfowany:

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]

Gra w golfa więcej: 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]przy założeniu, że dane wejściowe są wypełnione 0s.
Tylko ASCII

Ponadto, jeśli używasz Python 2, możesz to zrobićdef 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]
tylko ASCII

0

Mathematica, 114 (103)

Czysta funkcja: 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&

Nie golfowany:

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 &

Stosowanie:

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

Jeśli dozwolone są funkcje nazwane: 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

Stosowanie:

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==#, Myślę, że Quiet[x_]:=Quiet[x,All]π (Alt-P na Macu) pasuje do rozszerzonego ASCII.
CalculatorFeline

Nie można zastąpić #1 #2 #3z 1##? Nie zapomnij#==#1
CalculatorFeline

0

Współczynnik, 783 bajtów

Cóż, zajęło to wieczność.

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 ;

Zadzwoń { array of numbers } volume.


@StewieGriffin: PI całkowicie zapomniałem skrócić nazwy funkcji. Jednak niewiele pomoże.
kot
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.