Обчисліть об’єм об’єкта


18

Ви можете визначити об'єм об'єктів на основі заданого набору розмірів:

  • Об'єм сфери можна визначити, використовуючи одне число, радіус ( r)
  • Об'єм циліндра можна визначити, використовуючи два числа, радіус ( r) і висоту ( h)
  • Об'єм коробки можна визначити за допомогою трьох чисел, довжини ( l), ширини ( w) та висоти ( h)
  • Об'єм неправильної трикутної піраміди можна визначити за допомогою чотирьох чисел, довжини боків ( a, b, c) та висоти ( h).

Завдання полягає у визначенні обсягу об'єкта, що задається одним із таких входів:

  • Єдине число (r)або (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Два числа (r, h)або (r, h, 0, 0)=>V = pi*r^2*h
  • Три числа (l, w, h)або (l, w, h, 0)=>V = l*w*h
  • Чотири числа (a, b, c, h)=> V = (1/3)*A*h, де Aзадана формула Герона :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Правила та роз'яснення:

  • Вхід може бути як цілими чи / десятковими числами
  • Ви можете припустити, що всі вхідні розміри будуть позитивними
  • Якщо Pi закодований воно повинно бути з точністю до: 3.14159.
  • Вихід повинен мати щонайменше 6 значущих цифр, за винятком чисел, які можна точно представити меншою кількістю цифр. Ви можете виводити 3/4як 0.75, але 4/3має бути 1.33333(більше цифр у порядку)
    • Як округлювати неточні значення необов’язково
  • Поведінка неправильного введення не визначена
  • Стандартні правила вводу / виводу. Вхідним може бути список або окремі аргументи

Це кодовий гольф, тому найкоротше рішення в байтах виграє.

Тестові приклади:

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

Пов’язані, але різні .


1
Чи потрібен порядок розмірів, щоб бути порядком, зазначеним у запитанні?
Мего


@Mego, ви можете обрати ...
Стюі Гріффін

@StewieGriffin Varargs та потрапляння на масиви з динамічним розміром - це біль у моїй мові (принаймні для мене, для початківців). Чи можу я надати чотири функції для обробки кожного підрахунку аргументів?
кіт

Ви можете мати масив фіксованого розміру з останніми елементами, встановленими на нуль, якщо це необхідно. Що це повинно охоплювати, я думаю? Або ви можете перевантажувати функції, як у відповіді Haskell. Ви не можете мати різні функції з різними іменами.
Стюі Гріффін

Відповіді:


4

MATL , 57 53 51 44 байт

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

Вхід - це масив з 1, 2, 3 або 4 числами.

Спробуйте в Інтернеті!

Пояснення

Замість використання вкладених ifциклів, що є дорогим з точки зору байтів, він обчислює чотири можливі результати для будь-якого введення, а потім вибирає відповідний результат залежно від довжини введення.

При обчисленні результатів, хоча лише один з них має бути дійсним, інші не можуть помилитися. Це означає, наприклад, що індексація четвертого елемента вводу не дозволена, оскільки вхід може мати менше чотирьох елементів.

                    % 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

Яке видання формули Герона ви використовуєте?
Аддісон Кримп

@CoolestVeto Той, що має напівперіметр. Перша формула звідси
Луїс Мендо

Молодці @DonMuesli. Мені це вдалося, використовуючи "лише" 34 байти більше в MATLAB =)
Стюі Гріффін

9

Віци, 49 байт

Я думав, ти передав мені цю тарілку на тарілку, але я знайшов невирішеного помилку, щоб обійтись. Не зачепило мене, хоча.

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

В основному, оскільки вхід має певну довжину для різних функцій, ви ложкою подаєте мені синтаксис мого методу для виконання цього матеріалу. Отже, так, успіх!

Пояснення, один рядок:

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.

Введення приймається як аргументи командного рядка в точному зворотному порядку, оскільки вони відображаються у запитанні, без задніх нулів.

Спробуйте в Інтернеті!

Окрім того, ось щось, що зараз на стадії розробки.

Пакет Java з Vitsy

Зауважте, що цей пакет працює; це лише для того, щоб показати, як це буде працювати в майбутньому (документація для цього ще не завантажена), і це не гольф, і це дослівний переклад:

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
Однозначно правильний інструмент для роботи
Mego

5

C, 100 97 байт

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

редагуйте 1: видаліть непотрібні .десятки, дякую Імібіс!


2
Не може 4./3.бути просто 4/3.? А можна 2.і 12.просто бути 2і 12?
користувач253751

Ви абсолютно правильні. Спасибі!
Джош

4

JavaScript ES6, 129 126 125 116 114 90 байт

Збережено багато байтів (9) з чудовою формулою, завдяки Стюі Гріффін! Оскільки вхід повинен бути ненульовим, variable?вистачить для визначення-перевірки.

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}

Перевірте це!

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
З математикою? Здається легітимним.
Аддісон Кримп

Це помилки в Chrome 48, Uncaught SyntaxError: Unexpected token =(з посиланням на Z=a*a)
Патрік Робертс

@PatrickRoberts Використовуйте Firefox. Це дозволяє встановлювати параметри за замовчуванням всередині лямбда.
Conor O'Brien

Мені здається, що версія 4-arg не працює, і ти ніколи не використовуєш значення h, що здається трохи недоглядом.
Ніл

@Neil Huh, правда. Мені потрібно ще раз побачити цю формулу, Стюі видалив свій коментар ...
Conor O'Brien

3

Haskell, 114 109 107 101 99 байт

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)

Бере список номерів і повертає об'єм. Називай це так

v[7]

для сфери тощо. Функція є поліморфною для будь-якого типу, який реалізується sqrt(так, в основному Floatабо Double).

Конкурси на стислість не збираються. Але зауважте, наскільки це читабельно . Навіть якщо ви насправді не знаєте Haskell, ви можете сказати, що він робить досить легко. Синтаксис відповідності шаблону Haskell дозволяє дуже легко визначити дивні функції, які виконують щось зовсім інше, залежно від форми вводу.


1
(1/3)*(1/4)*h,,, чому б і ні h/12? Економить вам багато байтів!
Стюі Гріффін

1
Також варіант еквівалента Герона, який використовує Конор, здається набагато коротшим.
Стюі Гріффін

@StewieGriffin Мабуть, так. : -}
MathematicalOrchid

Haskell читається лише для infix math, який я не вважаю читабельним. Після цього ви отримаєте в .і #й $і вона стає Mathematica суп.
кіт

3

PowerShell, 165 161 байт

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]

Отже ... Багато ... доларів ... (31 з 161 символів - це $19,25% коду) ... але, врятувавши 4 байти завдяки Стіві Гріффін!

Ми беремо чотири входи, а потім прогресивно індексуємо псевдотермінальні заяви на їх основі у зворотному порядку. Наприклад, зовнішня (..., ...)[!$h]перевірка присутності четвертого входу. Якщо так, !$hволя дорівнює 0і перша половина виконується (об’єм неправильної трикутної піраміди). В іншому випадку, !$hз $h = $null(як це неініціалізовано) дорівнюватиме 1, тому він переходить до другої половини, яка сама по собі є псевдотерміналом [!$c]і так далі.

Це, ймовірно, близьке до оптимального, оскільки нібито скорочена формула, яку (наприклад) використовує C'O'Bʀɪᴇɴ , насправді на 2 байти довше в PowerShell завдяки відсутності ^оператора ... Єдина реальна економія надходить від (1/3)*(1/4)*A*$hгольфу на A*$h/12та налаштування $pпізніше, щоб зберегти пару байт замість тривалого [math]::PIдзвінка.



1

Серйозно, 65 59 55 байт

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

Спробуйте в Інтернеті!

Пояснення

Цей - дузі. Я збираюся розбити пояснення на кілька частин.

Головні сили:

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

Функція 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)

Функція 1:

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

Функція 2:

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

Функція 3 (21 байт; майже половина програми!)

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

Матлаб, 78 байт

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

Цілком впевнений, що він не може бути коротшим за це. ~b, ~cі ~d, 0якщо кожен з розмірів не дорівнює нулю. Формула з нульовим виміром просто дасть нуль. Таким чином, кожну з формул можна просто підсумувати. Ні ifі не elseпотрібно.

Назвіть це так (або спробуйте в Інтернеті тут ):

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
Яке божевілля змінних :-) Так, це здається важко скоротити далі
Луїс Мендо

Можливо, додайте посилання, щоб спробувати його в Інтернеті? ideone.com/6VZF9z
Луїс Мендо

0

Python 3 2, 127 119 116 байт

Кредит кому - то і Mego за їх допомогу з грою в гольф. Подяка також Cᴏɴᴏʀ O'Bʀɪᴇɴ та Джошу, коли я запозичив частину їхніх відповідей на цю.

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]

Безголівки:

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]

Гольф більше: 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] якщо припустити, що0 s.
Лише ASCII

Крім того, якщо ви використовуєте Python 2 замість цього, ви можете зробити це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]
лише ASCII

0

Математика, 114 (103)

Чиста функція: 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&

Безголівки:

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 &

Використання:

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

Якщо названі функції дозволені: 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

Використання:

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==#, Я думаю, Quiet[x_]:=Quiet[x,All]і π (Alt-P на Mac) вписується в розширений ASCII.
CalculatorFeline

Ви не можете замінити #1 #2 #3їх 1##? Не забувайте#==#1
CalculatorFeline

0

Фактор, 783 байт

Ну, це зайняло назавжди.

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 ;

Дзвінок { array of numbers } volume.


@StewieGriffin: PI зовсім забув скоротити назви функцій. Не дуже допоможе.
кіт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.