Рассчитать объем объекта


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 и получение динамических размеров - это боль в моем языке (по крайней мере, для меня, новичка в этом). Могу ли я предоставить четыре функции для обработки каждого числа аргументов?
кот

Вы можете иметь массив фиксированного размера с последними установленными нулями в случае необходимости. Это должно покрыть это, я думаю? Или вы можете перегрузить функции, как в ответе на 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 =)
Stewie Griffin

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
Определенно правильный инструмент для работы
Мего

5

С, 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: удалить ненужные десятичные ., спасибо Immibis!


2
Не может 4./3.быть просто 4/3.? А может 2.и 12.просто быть, 2и 12?
user253751

Вы абсолютно правы. Благодарность!
Джош

4

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

Благодаря Stewie Griffin удалось сэкономить много байтов (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. Это позволяет использовать параметры по умолчанию в лямбдах.
Конор О'Брайен,

Кажется, я не могу заставить работать версию с 4 аргументами ... и вы никогда не используете значение h, которое выглядит как недосмотр.
Нил

@ Нейл Да, правда. Мне нужно снова увидеть эту формулу, Стьюи удалил свой комментарий ...
Конор О'Брайен

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 доступен для чтения только для инфиксной математики, которую я не нахожу читаемой. После этого вы получите в .и #и $и она становится 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и первая половина будет выполнена (объем неправильной трехугольной пирамиды). В противном случае значение !$hwith $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

Matlab, 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 байтов

Кредит для кого-нибудь и Мего за всю их помощь в игре в гольф. Кредит также 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]

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]

Гольф больше: 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.
Только для 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-only

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&

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 &

Использование:

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.