Hitung volume suatu objek


18

Anda dapat menentukan volume objek berdasarkan kumpulan dimensi yang diberikan:

  • Volume bola dapat ditentukan menggunakan angka tunggal, jari-jari ( r)
  • Volume silinder dapat ditentukan dengan menggunakan dua angka, jari-jari ( r) dan tinggi ( h)
  • Volume kotak dapat ditentukan menggunakan tiga angka, panjang ( l), lebar ( w) dan tinggi ( h)
  • Volume piramida segitiga tidak teratur dapat ditentukan dengan menggunakan empat angka, panjang sisi ( a, b, c) dan tinggi ( h).

Tantangannya adalah untuk menentukan volume objek yang diberikan salah satu dari input berikut:

  • Satu angka (r)atau (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Dua angka (r, h)atau (r, h, 0, 0)=>V = pi*r^2*h
  • Tiga angka (l, w, h)atau (l, w, h, 0)=>V = l*w*h
  • Empat angka (a, b, c, h)=> V = (1/3)*A*h, di mana Adiberikan oleh rumus Bangau :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Aturan dan klarifikasi:

  • Input dapat berupa bilangan bulat dan / atau desimal
  • Anda dapat mengasumsikan semua dimensi input akan positif
  • Jika Pi sulit dikodekan itu harus akurat hingga: 3.14159.
  • Output harus memiliki setidaknya 6 digit signifikan, kecuali untuk angka yang dapat diwakili secara akurat dengan digit lebih sedikit. Anda dapat menampilkan 3/4sebagai 0.75, tetapi 4/3harus 1.33333(lebih banyak digit OK)
    • Cara membulatkan nilai yang tidak akurat adalah opsional
  • Perilaku untuk input yang tidak valid tidak ditentukan
  • Aturan standar untuk I / O. Input dapat berupa daftar atau argumen terpisah

Ini adalah kode golf, jadi solusi terpendek dalam byte menang.

Kasus uji:

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

Terkait, tetapi berbeda .


1
Apakah urutan dimensi diperlukan untuk urutan yang dinyatakan dalam pertanyaan?
Mego


@Mego, Anda dapat memilih ...
Stewie Griffin

@StewieGriffin Varargs dan mendapatkan array berukuran dinamis adalah rasa sakit dalam bahasa saya (setidaknya bagi saya, pemula dalam hal itu). Bisakah saya menyediakan empat fungsi untuk menangani setiap hitungan arg?
kucing

Anda dapat memiliki array berukuran tetap dengan elemen terakhir diatur ke nol jika perlu. Saya pikir itu harus mencakup itu? Atau Anda dapat membebani fungsi seperti pada jawaban Haskell. Anda tidak dapat memiliki fungsi yang berbeda dengan nama yang berbeda.
Stewie Griffin

Jawaban:


4

MATL , 57 53 51 44 byte

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

Input adalah array dengan angka 1, 2, 3 atau 4.

Cobalah online!

Penjelasan

Alih-alih menggunakan ifloop bersarang , yang mahal dalam hal byte, ini menghitung empat hasil yang mungkin untuk input apa pun, dan kemudian mengambil hasil yang sesuai tergantung pada panjang input.

Saat menghitung hasilnya, meskipun hanya satu yang valid, yang lain tidak bisa memberikan kesalahan. Ini berarti misalnya bahwa pengindeksan elemen keempat dari input tidak diperbolehkan, karena input mungkin memiliki kurang dari empat elemen.

                    % 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

Apa rumusan rumus Heron yang Anda gunakan?
Addison Crump

@ Coolestetoeto Yang dengan semiperimeter. Formula pertama dari sini
Luis Mendo

@ DonMuesli dilakukan dengan baik. Saya berhasil menggunakan "hanya" 34 byte lebih banyak di MATLAB =)
Stewie Griffin

9

Vitsy, 49 byte

Saya pikir Anda menyerahkan yang ini kepada saya di atas piring, tetapi saya menemukan bug yang belum terselesaikan untuk diatasi. Tapi tidak menyakitiku.

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

Pada dasarnya, dengan input yang panjang tertentu untuk fungsi yang berbeda, Anda sendok memberi saya sintaks metode saya untuk melakukan hal ini. Jadi, yay, sukses!

Penjelasan, satu baris sekaligus:

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.

Input diterima sebagai argumen baris perintah dalam kebalikan yang tepat seperti yang muncul dalam pertanyaan, tanpa nol tambahan.

Cobalah online!

Selain itu, ada sesuatu yang saat ini sedang dalam pengembangan.

Paket Java w / Vitsy

Perhatikan bahwa paket ini sedang dalam proses; ini hanya untuk menunjukkan bagaimana ini akan bekerja di masa depan (dokumentasi untuk ini belum diunggah) dan ini tidak di- golf, dan merupakan terjemahan literal:

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
Pasti alat yang tepat untuk pekerjaan itu
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)

sunting 1: hapus desimal yang tidak perlu ., terima kasih Immibis!


2
Tidak bisa 4./3.begitu 4/3.? Dan dapat 2.dan 12.hanya menjadi 2dan 12?
user253751

Anda benar sekali. Terima kasih!
Josh

4

JavaScript ES6, 129 126 125 116 114 90 byte

Menyimpan banyak byte (9) dengan formula yang luar biasa, terima kasih kepada Stewie Griffin! Karena input harus bukan nol, variable?cukup untuk pemeriksaan-definisi.

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}

Uji itu!

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
Dengan matematika? Kelihatannya mantap.
Addison Crump

Kesalahan ini di Chrome 48, Uncaught SyntaxError: Unexpected token =(merujuk ke Z=a*a)
Patrick Roberts

@ Patrickrickoberts Menggunakan Firefox. Ini memungkinkan untuk parameter default di dalam lambdas.
Conor O'Brien

Sepertinya saya tidak bisa mendapatkan versi 4-arg untuk bekerja ... dan Anda tidak pernah menggunakan nilai h, yang tampaknya agak kelewatan.
Neil

@Neil Huh, benar. Saya perlu melihat formula itu lagi, Stewie menghapus komentarnya ...
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)

Mengambil daftar angka dan mengembalikan volume. Sebut saja seperti

v[7]

untuk bola, dll. Fungsi ini polimorfik untuk semua jenis yang mengimplementasikan sqrt(jadi, pada dasarnya Floatatau Double).

Itu tidak akan memenangkan kontes untuk singkatnya. Tetapi perhatikan seberapa mudah dibaca itu. Bahkan jika Anda tidak benar-benar mengenal Haskell, Anda dapat mengetahui apa yang dilakukannya dengan mudah. Sintaks pencocokan pola Haskell membuatnya sangat mudah untuk mendefinisikan fungsi aneh yang melakukan sesuatu yang sangat berbeda tergantung pada bentuk input.


1
(1/3)*(1/4)*h,,, mengapa tidak h/12? Menghemat banyak byte!
Stewie Griffin

1
Juga, varian eon Heron yang digunakan Conor tampaknya jauh lebih pendek.
Stewie Griffin

@StewieGriffin Ternyata iya. : -}
MathematicalOrchid

Haskell hanya dapat dibaca untuk infiks matematika, yang menurut saya tidak dapat dibaca. Kemudian Anda masuk ke .dan #dan $dan itu menjadi Mathematica Soup.
kucing

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]

Jadi ... Banyak ... Dolar ... (31 dari 161 karakter adalah $ , untuk 19,25% dari kode) ... tetapi, disimpan 4 byte berkat Stewie Griffin!

Kami menerima empat input, dan kemudian secara progresif mengindeks ke pernyataan pseudo-ternary berdasarkan pada mereka dalam urutan terbalik. Misalnya, (..., ...)[!$h]tes luar apakah input keempat hadir. Jika demikian, !$hkemauan sama 0dan babak pertama dieksekusi (volume piramida triagonal tidak beraturan). Kalau tidak, !$hdengan $h = $null(seperti yang tidak diinisialisasi) akan sama 1, jadi ia pergi ke babak kedua, yang itu sendiri adalah pseudo-ternary berdasarkan [!$c]dan seterusnya.

Ini kemungkinan mendekati optimal, karena rumus yang seharusnya lebih pendek yang (misalnya) digunakan oleh Cᴏɴᴏʀ O'Bʀɪᴇɴ sebenarnya 2 byte lebih lama di PowerShell berkat kurangnya ^operator ... Satu-satunya penghematan nyata berasal dari (1/3)*(1/4)*A*$hbermain golf A*$h/12, dan pengaturan $pnanti untuk menyimpan beberapa byte alih-alih [math]::PIpanggilan yang panjang .


1

CJam, 67 66 byte

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

Saya akan segera memperpendeknya. Cobalah online !

Penjelasan yang akan datang.


1

Serius, 65 59 55 byte

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

Cobalah online!

Penjelasan

Yang ini doozy. Saya akan memecah penjelasan menjadi beberapa bagian.

Tubuh utama:

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

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

Fungsi 1:

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

Fungsi 2:

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

Fungsi 3 (21 byte; hampir setengah dari panjang program!)

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;

Cukup yakin itu tidak bisa lebih pendek dari ini. ~b, ~cdan ~d, 0jika masing-masing dimensi bukan nol. Rumus dengan dimensi nol hanya akan memberikan nol. Dengan begitu, masing-masing formula dapat dengan mudah dijumlahkan. Tidak ifdanelse wajib

Sebut saja seperti ini (atau coba online di sini ):

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
Apa kegilaan variabel :-) Ya, ini tampaknya sulit untuk dipersingkat lebih lanjut
Luis Mendo

Mungkin menambahkan tautan untuk mencobanya online? ideone.com/6VZF9z
Luis Mendo

0

Python 3 2, 127 119 116 byte

Penghargaan kepada seseorang dan Mego atas semua bantuan mereka dalam bermain golf. Penghargaan juga untuk Cᴏɴᴏʀ O'Bʀɪᴇɴ dan Josh ketika saya meminjam sebagian dari jawaban mereka untuk yang satu ini.

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]

Tidak Disatukan:

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]

Golf lebih banyak:, 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]dengan asumsi input diisi dengan 0s.
ASCII

Selain itu, jika Anda menggunakan Python 2 sebagai gantinya, Anda dapat melakukannyadef 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

Mathematica, 114 (103)

Fungsi murni: 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&

Tidak Disatukan:

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 &

Pemakaian:

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

Jika fungsi-fungsi yang disebutkan diizinkan: 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

Pemakaian:

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==#, Saya pikir Quiet[x_]:=Quiet[x,All]dan π (Alt-P pada Mac) cocok untuk ASCII yang diperluas.
CalculatorFeline

Tidak bisakah Anda ganti #1 #2 #3dengan 1##? Jangan lupa#==#1
CalculatorFeline

0

Faktor, 783 byte

Yah, ini butuh waktu lama.

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 ;

Panggil { array of numbers } volume.


@StewieGriffin: PI benar-benar lupa mempersingkat nama fungsi. Tidak akan banyak membantu.
kucing
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.