Calcola il volume di un oggetto


18

È possibile determinare il volume degli oggetti in base a un determinato set di dimensioni:

  • Il volume di una sfera può essere determinato utilizzando un singolo numero, il raggio ( r)
  • Il volume di un cilindro può essere determinato usando due numeri, il raggio ( r) e l'altezza ( h)
  • Il volume di una scatola può essere determinato usando tre numeri, la lunghezza ( l), la larghezza ( w) e l'altezza ( h)
  • Il volume di una piramide triangolare irregolare può essere determinato utilizzando quattro numeri, le lunghezze laterali ( a, b, c) e l'altezza ( h).

La sfida è determinare il volume di un oggetto dato uno dei seguenti input:

  • Un singolo numero (r)o (r, 0, 0, 0)=>V = 4/3*pi*r^3
  • Due numeri (r, h)o (r, h, 0, 0)=>V = pi*r^2*h
  • Tre numeri (l, w, h)o (l, w, h, 0)=>V = l*w*h
  • Quattro numeri (a, b, c, h)=> V = (1/3)*A*h, dove Aè dato dalla formula di Heron :A = 1/4*sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c))

Regole e chiarimenti:

  • L'input può essere sia numeri interi che / o decimali
  • Puoi presumere che tutte le dimensioni di input siano positive
  • Se Pi è codificato difficile deve essere accurato fino a: 3.14159.
  • L'output deve contenere almeno 6 cifre significative, ad eccezione dei numeri che possono essere rappresentati accuratamente con meno cifre. È possibile generare 3/4come 0.75, ma 4/3deve essere 1.33333(più cifre sono OK)
    • Come arrotondare valori imprecisi è facoltativo
  • Il comportamento per input non valido non è definito
  • Regole standard per I / O. L'input può essere un elenco o argomenti separati

Questo è il golf del codice, quindi vince la soluzione più breve in byte.

Casi test:

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

Correlato, ma diverso .


1
L'ordine delle dimensioni deve essere quello indicato nella domanda?
Mego


@Mego, puoi scegliere ...
Stewie Griffin

@StewieGriffin Varargs e arrivare ad array di dimensioni dinamiche è un dolore nella mia lingua (almeno per me, un principiante). Posso fornire quattro funzioni per gestire ogni conteggio degli arg?
gatto

Se necessario, è possibile disporre di un array di dimensioni fisse con gli ultimi elementi impostati su zero. Dovrebbe coprirlo penso? Oppure puoi sovraccaricare le funzioni come nella risposta di Haskell. Non puoi avere funzioni diverse con nomi diversi.
Stewie Griffin,

Risposte:


4

MATL , 57 53 51 44 byte

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

L'input è un array con 1, 2, 3 o 4 numeri.

Provalo online!

Spiegazione

Invece di utilizzare ifloop nidificati , che è costoso in termini di byte, calcola quattro possibili risultati per qualsiasi input, quindi seleziona il risultato appropriato in base alla lunghezza dell'input.

Nel calcolare i risultati, anche se solo uno di essi deve essere valido, gli altri non possono dare errori. Ciò significa ad esempio che non è consentito indicizzare il quarto elemento dell'input, poiché l'input può avere meno di quattro elementi.

                    % 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

Quale interpretazione della formula di Heron stai usando?
Addison Crump

@CoolestVeto Quello con il semiperimetro. Prima formula da qui
Luis Mendo il

Ben fatto @DonMuesli. L'ho gestito usando "solo" 34 byte in più in MATLAB =)
Stewie Griffin

9

Vitsy, 49 byte

Pensavo che me lo avessi consegnato su un piatto, ma ho trovato un bug irrisolto per aggirare. Non mi ha fatto male, però.

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

Fondamentalmente, con l'input che è una certa lunghezza per diverse funzioni, mi dai da mangiare la mia sintassi del metodo per fare queste cose. Quindi, sì, successo!

Spiegazione, una riga alla volta:

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.

L'input è accettato come argomento da riga di comando nell'esatto contrario come appare nella domanda, senza zero finali.

Provalo online!

A parte questo, ecco qualcosa che è attualmente in fase di sviluppo.

Java con pacchetto Vitsy

Si noti che questo pacchetto è in fase di elaborazione; questo è solo per mostrare come funzionerà in futuro (la documentazione per questo non è ancora stata caricata) e non è giocata a golf, ed è una traduzione letterale:

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
Sicuramente lo strumento giusto per il lavoro
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)

modifica 1: rimuovi i decimali non necessari ., grazie Immibis!


2
Non puoi 4./3.essere 4/3.? E può 2.e 12.basta essere 2e 12?
user253751

Hai assolutamente ragione. Grazie!
Josh

4

JavaScript ES6, 129 126 125 116 114 90 byte

Hai salvato molti byte (9) con una formula meravigliosa, grazie a Stewie Griffin! Poiché l'input deve essere diverso da zero, variable?sarà sufficiente per un controllo di definizione.

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}

Provalo!

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
Con la matematica? Sembra giusto.
Addison Crump

Questo errore su Chrome 48, Uncaught SyntaxError: Unexpected token =(riferito a Z=a*a)
Patrick Roberts

@PatrickRoberts Usa Firefox. Consente parametri predefiniti all'interno di lambda.
Conor O'Brien,

Non riesco a far funzionare la versione di 4-arg ... e non ne usi mai il valore h, il che sembra un po 'una svista.
Neil,

@Neil Huh, vero. Dovrò rivedere quella formula, Stewie cancellò il suo commento ...
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)

Prende un elenco di numeri e restituisce un volume. Chiamalo come

v[7]

per una sfera, ecc. La funzione è polimorfica per qualsiasi tipo che implementa sqrt(quindi, sostanzialmente Floato Double).

Non vincerà alcun concorso per brevità. Ma nota quanto sia leggibile . Anche se non conosci davvero Haskell, puoi dire cosa fa abbastanza facilmente. La sintassi di corrispondenza del modello di Haskell rende davvero facile definire strane funzioni che fanno qualcosa di totalmente diverso a seconda della forma dell'input.


1
(1/3)*(1/4)*h,,, perché no h/12? Ti fa risparmiare un sacco di byte!
Stewie Griffin

1
Inoltre, la variante dell'eq di Heron utilizzata da Conor sembra essere molto più breve.
Stewie Griffin

@StewieGriffin Apparentemente sì. : -}
MathematicalOrchid

Haskell è leggibile solo per la matematica infix, che non trovo leggibile. Poi si entra in .e #ed $e diventa Mathematica Soup.
gatto

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]

Quindi ... Molti ... Dollari ... (31 dei 161 caratteri sono $, per il 19,25% del codice) ... ma, salvato 4 byte grazie a Stewie Griffin!

Prendiamo in considerazione quattro input e quindi indicizziamo progressivamente le dichiarazioni pseudo-ternarie basate su di esse in ordine inverso. Ad esempio, l'esterno (..., ...)[!$h]verifica se è presente il quarto input. In tal caso, la !$hvolontà sarà uguale 0e verrà eseguita la prima metà (il volume di una piramide triagonale irregolare). Altrimenti, !$hcon $h = $null(in quanto non inizializzato) sarà uguale 1, quindi va alla seconda metà, che a sua volta è uno pseudo-ternario basato su [!$c]e così via.

Questo è probabilmente vicino all'ottimale, poiché la formula presumibilmente più breve che (ad esempio) Cᴏɴᴏʀ O'Bʀɪᴇɴ sta usando è in realtà 2 byte più lunga in PowerShell grazie alla mancanza di un ^operatore ... L'unico vero risparmio proviene dal (1/3)*(1/4)*A*$hgolf a A*$h/12, e impostazione in $pseguito per salvare un paio di byte invece della lunga [math]::PIchiamata.


1

CJam, 67 66 byte

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

Lavorerò per accorciarlo presto. Provalo online !

Spiegazione a venire.


1

Scherzi a parte, 65 59 55 byte

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

Provalo online!

Spiegazione

Questo è un doozy. Ho intenzione di spezzare la spiegazione in più parti.

Corpo principale:

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

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

Funzione 1:

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

Funzione 2:

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

Funzione 3 (21 byte; quasi la metà della lunghezza del programma!)

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;

Abbastanza sicuro che non può essere più breve di questo. ~b, ~cE ~d, sono 0se ciascuna delle dimensioni sono non-zero. Una formula con una dimensione zero darà solo zero. In questo modo, ciascuna delle formule può essere semplicemente riassunta. No ife elserichiesto.

Chiamalo così (o provalo online qui ):

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
Che follia di variabili :-) Sì, sembra difficile accorciare ulteriormente
Luis Mendo

Forse aggiungi un link per provarlo online? ideone.com/6VZF9z
Luis Mendo

0

Python 3 2, 127 119 116 byte

Ringraziamo qualcuno e Mego per tutto il loro aiuto nel golf. Ringrazio anche Cᴏɴᴏʀ O'Bʀɪᴇɴ e Josh mentre prendevo in prestito parti delle loro risposte per questo.

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]

Golfato di più:, 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]supponendo che l'input sia riempito con 0s.
ASCII il

Inoltre, se usi Python 2 invece, puoi farlodef 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]
solo ASCII il

0

Mathematica, 114 (103)

Funzione pura: 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 &

Uso:

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

Se sono consentite funzioni nominate: 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

Uso:

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==#, Penso Quiet[x_]:=Quiet[x,All]e π (Alt-P su Mac) si adatta in ASCII esteso.
Calcolatrice

Non puoi sostituirlo #1 #2 #3con 1##? Non dimenticare#==#1
CalcolatriceFeline

0

Fattore, 783 byte

Bene, ci è voluto per sempre.

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 ;

Chiama { array of numbers } volume.


@StewieGriffin: PI ha completamente dimenticato di abbreviare i nomi delle funzioni. Non aiuterà molto, però.
gatto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.