Tính thể tích của một vật


18

Bạn có thể xác định khối lượng của các đối tượng dựa trên một nhóm kích thước nhất định:

  • Thể tích của một hình cầu có thể được xác định bằng một số duy nhất, bán kính ( r)
  • Thể tích của hình trụ có thể được xác định bằng hai số, bán kính ( r) và chiều cao ( h)
  • Thể tích của một hộp có thể được xác định bằng ba số, chiều dài (l ), chiều rộng ( w) và chiều cao ( h)
  • Thể tích của một hình chóp tam giác không đều có thể được xác định bằng bốn số, độ dài cạnh (a, b, c ) và chiều cao ( h).

Thách thức là xác định khối lượng của một đối tượng được cung cấp một trong các đầu vào sau:

  • Một số duy nhất (r) hoặc (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Hai số (r, h) hoặc (r, h, 0, 0)=>V = pi*r^2*h
  • Ba số (l, w, h) hoặc (l, w, h, 0)=>V = l*w*h
  • Bốn số (a, b, c, h)=> V = (1/3)*A*h, Ađược đưa ra theo công thức của Heron :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Các quy tắc và làm rõ:

  • Đầu vào có thể là cả số nguyên và / hoặc số thập phân
  • Bạn có thể cho rằng tất cả các kích thước đầu vào sẽ là dương
  • Nếu Pi được mã hóa cứng, nó phải chính xác tới: 3.14159 .
  • Đầu ra phải có ít nhất 6 chữ số có nghĩa, ngoại trừ các số có thể được biểu diễn chính xác với ít chữ số hơn. Bạn có thể xuất 3/4dưới dạng 0.75, nhưng 4/3phải 1.33333(nhiều chữ số hơn là OK)
    • Cách làm tròn các giá trị không chính xác là tùy chọn
  • Hành vi cho đầu vào không hợp lệ là không xác định
  • Quy tắc chuẩn cho I / O. Đầu vào có thể là danh sách hoặc các đối số riêng biệt

Đây là mã golf, vì vậy giải pháp ngắn nhất trong byte thắng.

Các trường hợp thử nghiệm:

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ên quan, nhưng khác nhau .


1
Là thứ tự của các kích thước cần thiết phải là thứ tự được nêu trong câu hỏi?
Mego


@Mego, bạn có thể chọn ...
Stewie Griffin

@StewieGriffin Varargs và nhận được các mảng có kích thước động là một nỗi đau trong ngôn ngữ của tôi (ít nhất là đối với tôi, người mới bắt đầu sử dụng nó). Tôi có thể cung cấp bốn hàm để xử lý mỗi số arg không?
mèo

Bạn có thể có một mảng có kích thước cố định với các phần tử cuối được đặt thành 0 nếu cần. Điều đó sẽ bao gồm nó tôi nghĩ? Hoặc bạn có thể quá tải các chức năng như trong câu trả lời của Haskell. Bạn không thể có các chức năng khác nhau với các tên khác nhau.
Stewie Griffin

Câu trả lời:


4

MATL , 57 53 51 44 byte

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

Đầu vào là một mảng với 1, 2, 3 hoặc 4 số.

Hãy thử trực tuyến!

Giải trình

Thay vì sử dụng các ifvòng lặp lồng nhau , tốn kém về byte, điều này sẽ tính toán bốn kết quả có thể cho bất kỳ đầu vào nào, sau đó chọn kết quả phù hợp tùy thuộc vào độ dài đầu vào.

Khi tính toán kết quả, mặc dù chỉ một trong số chúng cần hợp lệ, những cái khác không thể đưa ra lỗi. Điều này có nghĩa là, ví dụ, việc lập chỉ mục phần tử thứ tư của đầu vào là không được phép, bởi vì đầu vào có thể có ít hơn bốn phần tử.

                    % 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

Bạn đang sử dụng công thức nào của Heron?
Addison Crump

@CoolestVeto Cái nào có bán kính. Công thức đầu tiên từ đây
Luis Mendo

Làm tốt lắm @DonMuesli. Tôi đã quản lý nó bằng cách sử dụng "chỉ" thêm 34 byte trong MATLAB =)
Stewie Griffin

9

Vitsy, 49 byte

Tôi nghĩ rằng bạn đã đưa cái này cho tôi trên một cái đĩa, nhưng tôi đã tìm thấy một lỗi chưa được giải quyết để khắc phục. Không làm tổn thương tôi, mặc dù.

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

Về cơ bản, với đầu vào là một độ dài nhất định cho các chức năng khác nhau, bạn đưa thìa cho tôi cú pháp phương thức của tôi để thực hiện công cụ này. Vì vậy, yay, thành công!

Giải thích, một dòng tại một thời điểm:

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.

Đầu vào được chấp nhận dưới dạng đối số dòng lệnh theo chiều ngược lại chính xác khi chúng xuất hiện trong câu hỏi, không có số 0 ở cuối.

Hãy thử trực tuyến!

Bên cạnh đó, đây là một cái gì đó hiện đang được phát triển.

Gói w / Vitsy Java

Lưu ý rằng gói này đang được tiến hành; đây chỉ là để cho thấy nó sẽ hoạt động như thế nào trong tương lai (tài liệu cho việc này chưa được tải lên) và nó không được đánh gôn, và là một bản dịch theo nghĩa đen:

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
Chắc chắn là công cụ phù hợp cho công việc
Mego

5

C, 100 97 byte

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

chỉnh sửa 1: xóa số thập phân không cần thiết ., cảm ơn Immibis!


2
Không 4./3.thể 4/3.nào? Và có thể 2.12.chỉ là 212?
dùng253751

Bạn hoàn toàn chính xác. Cảm ơn!
Josh

4

JavaScript ES6, 129 126 125 116 114 90 byte

Đã lưu rất nhiều byte (9) với công thức tuyệt vời, nhờ Stewie Griffin! Vì đầu vào phải khác 0, variable?sẽ đủ cho kiểm tra xác định.

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}

Kiểm tra nó ra!

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
Với môn toán? Có vẻ hợp pháp.
Addison Crump

Lỗi này trên Chrome 48, Uncaught SyntaxError: Unexpected token =(tham khảo Z=a*a)
Patrick Roberts

@PatrickRoberts Sử dụng Firefox. Nó cho phép các tham số mặc định bên trong lambdas.
Conor O'Brien

Tôi dường như không thể làm cho phiên bản 4-arg hoạt động ... và bạn không bao giờ sử dụng giá trị của h, điều này có vẻ hơi quá.
Neil

@Neil Huh, đúng. Tôi sẽ cần phải xem lại công thức đó, Stewie đã xóa bình luận của mình ...
Conor O'Brien

3

Haskell, 114 109 107 101 99 byte

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)

Đưa ra một danh sách các số và trả về một khối lượng. Gọi nó như thế

v[7]

cho một hình cầu, vv Hàm này là đa hình cho bất kỳ loại nào thực hiện sqrt(vì vậy, về cơ bản FloathoặcDouble ).

Nó sẽ không chiến thắng bất kỳ cuộc thi nào cho sự ngắn gọn. Nhưng lưu ý làm thế nào nó có thể đọc được. Ngay cả khi bạn không thực sự biết Haskell, bạn có thể nói những gì nó làm khá dễ dàng. Cú pháp khớp mẫu của Haskell giúp dễ dàng xác định các hàm lạ thực hiện một cái gì đó hoàn toàn khác nhau tùy thuộc vào hình dạng của đầu vào.


1
(1/3)*(1/4)*h,,, tại sao không h/12? Tiết kiệm cho bạn rất nhiều byte!
Stewie Griffin

1
Ngoài ra, biến thể của Heron's mà Conor sử dụng dường như ngắn hơn rất nhiều.
Stewie Griffin

@StewieGriffin Rõ ràng là có. : -}
Toán học,

Haskell chỉ có thể đọc được đối với toán học infix mà tôi không thể đọc được. Sau đó, bạn nhận được vào .#$và nó trở thành Mathematica Soup.
mèo

3

PowerShell, 165 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]

Vậy ... Nhiều ... Đô la ... (31 trong số 161 ký tự là $ , chiếm 19,25% mã) ... nhưng, đã lưu được 4 byte nhờ Stewie Griffin!

Chúng tôi đưa vào bốn đầu vào, và sau đó lập chỉ mục dần dần thành các báo cáo giả ba chiều dựa trên chúng theo thứ tự ngược lại. Ví dụ, các (..., ...)[!$h]kiểm tra bên ngoài cho dù đầu vào thứ tư là hiện tại. Nếu vậy, ý !$hchí bằng nhau 0và nửa đầu được thực hiện (thể tích của một hình chóp ba cạnh không đều). Mặt khác, !$hvới $h = $null(vì nó chưa được khởi tạo) sẽ bằng nhau 1, vì vậy nó sẽ chuyển sang nửa thứ hai, bản thân nó là một giả ba dựa trên [!$c]và như vậy.

Điều này có thể gần với tối ưu, vì công thức được cho là ngắn hơn mà (ví dụ) Cᴏɴᴏʀ O'Bʀɪᴇɴ đang sử dụng thực sự dài hơn 2 byte trong PowerShell nhờ thiếu người ^vận hành ... Tiết kiệm thực sự duy nhất đến từ việc (1/3)*(1/4)*A*$hchơi golf A*$h/12và thiết lập $psau để lưu một vài byte thay vì [math]::PIcuộc gọi dài .



1

Nghiêm túc, 65 59 55 byte

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

Hãy thử trực tuyến!

Giải trình

Đây là một doozy. Tôi sẽ chia lời giải thích thành nhiều phần.

Cơ thể chính:

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

Chức năng 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)

Chức năng 1:

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

Chức năng 2:

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

Hàm 3 (21 byte; gần một nửa thời lượng chương trình!)

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 byte

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

Chắc chắn rằng nó không thể nhận được bất kỳ ngắn hơn này. ~b, ~c~d, là 0nếu mỗi người trong số các kích thước là khác không. Một công thức có thứ nguyên bằng 0 sẽ chỉ cho số không. Bằng cách đó, mỗi công thức có thể được tóm tắt. Không ifelse bắt buộc.

Gọi nó như thế này (hoặc thử trực tuyến tại đây ):

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
Thật là một sự điên rồ của các biến số :-) Vâng, điều này dường như khó rút ngắn hơn nữa
Luis Mendo

Có thể thêm một liên kết để thử nó trực tuyến? ideone.com/6VZF9z
Luis Mendo

0

Con trăn 3 2, 127 119 116 byte

Tín dụng cho ai đóMego cho tất cả sự giúp đỡ của họ với việc chơi golf. Tín dụng cho Cᴏɴᴏʀ O'BʀɪᴇɴJosh khi tôi mượn một phần câu trả lời của họ cho câu hỏi này.

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]

Ung dung:

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]

Golfed hơn : 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], giả sử đầu vào được đệm bằng 0s.
ASCII - chỉ

Ngoài ra, nếu bạn sử dụng Python 2 thay vào đó, bạn có thể làmdef 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]
chỉ có ASCII

0

Toán học, 114 (103)

Hàm thuần túy: 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&

Ung dung:

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 &

Sử dụng:

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

Nếu chức năng được đặt tên được cho phép: 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

Sử dụng:

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==#, Tôi nghĩ Quiet[x_]:=Quiet[x,All]và π (Alt-P trên máy Mac) phù hợp với ASCII mở rộng.
Máy

Bạn không thể thay thế #1 #2 #3bằng 1##? Đừng quên#==#1
Máy

0

Yếu tố, 783 byte

Vâng, điều này mất mãi mãi.

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 ;

Gọi { array of numbers } volume.


@StewieGriffin: PI hoàn toàn quên rút ngắn tên của các hàm. Mặc dù không giúp được gì nhiều.
mèo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.