Cerchi N-dimensionali!


16

Scrivi un programma che accetta due numeri come input. Il primo è il numero di dimensioni: 0 per un punto, 1 per una linea retta, 2 per un cerchio, 3 per una sfera. Il secondo numero è il raggio dell'oggetto o, se è monodimensionale, il numero stesso. Uscita 0 per 0 dimensioni. L'output è la lunghezza / area / volume dell'oggetto.

Se chiamiamo il primo numero n, il secondo re l'output x, otteniamo che:

  • per n = 0, x = 1

  • per n = 1, x = 2 × r

  • per n = 2, x = r 2 × π

  • per n = 3, x = ( 4 / 3 ) × R 3 × π

  • e così via ... se vuoi, però.

Appunti:

  • I casi in cui uno o entrambi i numeri sono negativi o quando il primo numero non è intero, non devono essere coperti.

  • Il programma non deve leggere da nessun file e l'unico input sono quei due numeri.

  • L'output deve utilizzare solo numeri (ad es. Non "14 * pi") e deve avere una precisione di almeno due cifre decimali.

  • Per quanto riguarda n = 0, puoi produrre 0 se accorcia il codice.

  • Swag extra per una risposta che copre anche "sfere" a 4 e più dimensioni!

  • È , quindi vince la risposta più breve in byte!

Esempi:

 1 1 -> 2

 2 3 -> 28,27

 3 1 -> 4,19

 3 4,5 -> 381,70

 1 9.379 -> 18.758

 0 48 -> 1

2
Sìì! Adoro le false equazioni di MathJax nei post!
RudolfJelin,

1
Non per criticare, ma non vedo come una linea possa essere considerata come un cerchio 1d ...
xem

10
@xem Considera un cerchio come tutti i punti che si trovano a una determinata distanza dal centro
Luis Mendo,

3
I tipi di matematica chiamerebbero queste "palle" di varie dimensioni. L'insieme di punti con distanza dall'origine == rè la sfera, l'insieme di punti con distanza dall'origine <= rè la sfera. Quindi questi sono 0-ball = point, 1-ball = segment, 2-ball = disk, 3-ball = ball, 4-ball, 5-ball, ecc. (elencato come " n-ball = nome comune").
Eric Towers,

3
"Uscita 0 per 0 dimensioni" e "per n = 0, x = 1" si contraddicono. Potresti sceglierne uno (o chiarire che entrambi sono ammessi)?
Paŭlo Ebermann,

Risposte:


7

Gelatina , 13 byte + swag extra

÷2µØP*÷!
ç×*@

Provalo online!

Funziona per qualsiasi dimensione, purché il valore fisso di π prodotto da ØP( 3.141592653589793) sia sufficientemente preciso.

Come?

÷2µØP*÷! - Link 1: n, r
÷2       - n / 2
  µ      - monadic chain separation
   ØP    - π (3.141592653589793)
     *   - exponentiate: π^(n/2)
       ! - Pi(n/2): Gamma(n/2 + 1)
      ÷  - divide: π^(n/2) / Gamma(n/2 + 1)

ç×*@     - Main link: n, r
ç        - call last link (1) as a dyad: π^(n/2) / Gamma(n/2 + 1)
  *@     - exponentiate with reversed @rguments: r^n
 ×       - multiply: r^n * π^(n/2) / Gamma(n/2 + 1)

1
Ben fatto per aver battuto Mathematica!
CJ Dennis,

Complimenti, hai vinto!
RudolfJelin,

13

Mathematica, 18 byte, fino a ~ 168,15 trilioni di dimensioni

Pi^(a=.5#)/a!#2^#&

Funzione anonima. Accetta due numeri come input e restituisce un numero inesatto come output. Funziona con qualsiasi numero di dimensioni. Uscite 1.per n = 0. Utilizza la formula dal volume di una n-ball su Wikipedia.

Spiegazione

Stiamo tentando di calcolare π n / 2 / Γ ( n / 2 + 1) · R n , o N[Pi^(n/2)/Gamma[n/2 + 1] R^n]in Mathematica. Nel nostro caso, #(primo argomento) è n e #2(secondo argomento) è R . Questo ci lascia con N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, che può essere giocato come segue:

N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &
Pi^(.5#)/Gamma[.5# + 1] #2^# &    (* replace exact with approximate numbers*)
Pi^(.5#)/(.5#)! #2^# &            (* n! == Gamma[n + 1] *)
Pi^(a=.5#)/a! #2^# &              (* replace repeated .5# *)
Pi^(a=.5#)/a!#2^#&                (* remove whitespace *)

e quindi, il nostro programma originale.


Bella risposta - è stato veloce! Solo per chiarimenti: a quante cifre l'output è corretto? Quante dimensioni è possibile calcolare?
RudolfJelin,

@ RudolfL.Jelínek Produce circa 5 cifre significative e funziona per tutti n fino a 168.146.894.169.516 per r = 1 (sebbene con meno cifre).
LegionMammal978,

@ LegionMammal978 quale formula? Sono abbastanza sicuro che non usi la funzione gamma lì
Angs

@Angs n ! = Γ  (  n + 1).
LegionMammal978,

2
Oh, !funziona anche per i non integrali. Usare Mathematica per questo sembra quasi imbrogliare ... :)
Angs,

6

JavaScript (ES6), 45 byte + swag extra

La formula ricorsiva di Wikipedia , dovrebbe funzionare per qualsiasi numero di dimensioni

f=(n,r)=>n<2?n?2*r:1:f(n-2,r)*2*Math.PI*r*r/n

6

R, 75 40 38 byte (più swag extra)

Bene, sembra che potrei giocare a golf cedendo e usando la funzione gamma piuttosto che le funzioni ricorsive.

function(n,r)pi^(n/2)/gamma(n/2+1)*r^n

Definisce una funzione anonima per calcolare il volume di nun'ipersfera tridimensionale del raggio r.

Qualche esempio:

1 1 -> 2

0 48 -> 1

2 3 -> 28.27433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Soluzione Swagless, 38 34 byte

Per pochi byte in meno, puoi avere una funzione anonima che funziona solo per le dimensioni da 1 a 3. Restituisce numeric(0)per n=0e NAper n>3. ( numeric(0)è un vettore numerico di lunghezza 0; NAè per "non disponibile".) Le prestazioni sono altrimenti identiche alla soluzione generale sopra.

function(n,r)c(1,pi,4/3*pi)[n]*r^n

1
₊₁ per SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin,

5

Haskell, 74 65 36 byte + swag extra

0%r=1
1%r=2*r
n%r=2*pi*r^2/n*(n-2)%r

Formula ricorsiva, funziona per tutte le dimensioni che possono essere presentate esattamente come un numero in virgola mobile a precisione doppia ma verranno ripetute all'infinito per dimensioni non integrali. La vecchia versione per amore della posteriorità:

n%r=(max 1$1-(-1)**n)*(2*pi)^(floor$n/2)*r**n/product[n,n-2..1.1]

Funziona per tutte le dimensioni. Usa la formula dal manifesto tau . product[n,n-2..1.1]è un doppio hack fattoriale che non conta zeron==2


5

JavaScript, 61 51 49 43 byte

Le dimensioni 0-3 sono supportate perché non esiste la quarta dimensione .

Grazie a @Hedi per aver salvato 7 byte

d=(n,r)=>r**n*(n<2?n+1:Math.PI*(n<3?1:4/3))

Crea funzione d. Quindi aumenta ralla nth potenza e quindi la moltiplica per un numero a seconda ndell'utilizzo di operatori ternari. Uscite 1pern=0

Fornisce un output di almeno 2 decimali (10+ dp)

Ecco uno snippet di snack!

var N = document.getElementById("n");
var R = document.getElementById("r");
N.value="3";//default
R.value="4.5";//default
d=(n,r)=>r**n*(n<2?n+1:Math.PI*(n<3?1:4/3));
var b = document.getElementById("b");
b.onclick = function() {
  var s = document.getElementById("s");
  var n = document.getElementById("n").value;
  var r = document.getElementById("r").value;
  s.textContent = d(parseFloat(n),parseFloat(r));
}
span {border:1px solid black;padding:10px;font-size:30px;}
Value of n: <input id="n" type="number"></input>
Value of r: <input id="r" type="number"></input><br>
<button id="b">Calculate!</button><br><br><br>
<span id="s">THERE IS NO 4TH DIMENSION</span>


Batti la mia soluzione non pubblicata di ... di molto. +1!
RudolfJelin,

6
che video stupido ...
Visualizza nome

1
@SargeBorsch Almeno dimostra il mio punto :)
Kritixi Lithos,

2
@SargeBorsch Haha yup stupido video - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- A quel punto sembra dire che c'è una quarta dimensione, ma nessuna prima, seconda o terza!
Level River St,

1
@LevelRiverSt Bene, quello è stato il primo risultato che sono stato sul web ¯ \ _ (ツ) _ / ¯
Kritixi Lithos

3

MATL , 17 byte

3:^[2P4*P/3]*1hi)

Funziona solo con 3 dimensioni. Gli ingressi sono in ordine inverso, ovvero:, rquindi n.

Provalo online!

Considera r=3, n=2come esempio.

3:         % Push array [1 2 3]
           % STACK: [1 2 3]
^          % Take r implicitly, and raise it to [1 2 3] element-wise
           % STACK: [3 9 27]
[2P4*P/3]  % Push array [2 pi 4*pi/3]
           % STACK: [3 9 27], [2 pi 4*pi/3]
*          % Multiply element-wise
           % STACK: [6 28.2743 113.0973]
1h         % Append 1
           % STACK: [6 28.2743 113.0973, 1]
i)         % Input n and use it as modular index into the array. Display implicitly
           % STACK: 28.2743

2

Java / C / C ++ / C #, 69 67 byte + swag extra!

Modifica: salvato 2 byte grazie a @AlexRacer

Una funzione diadica - il primo argomento è il numero di dimensioni, il secondo è il raggio della palla n.

float v(int n,float r){return n<1?1:n<2?2*r:6.283f*r*r*v(n-2,r)/n;}

Formula ricorsiva per il volume di una palla n: V n = (2πr 2 V n-2 )n

Whoa! Java (il mio linguaggio di prova) batte Scala qui, grazie alla ?:sintassi ternaria concisa! Questa funzione è sintatticamente corretta in tutte e 4 le lingue nell'intestazione e l'ho testata con C (MinGW GCC 5.4.0) e C # (VS Ultimate 2016, C # 6.0). Suppongo che funzionerà anche in C ++, quindi lì. Poiché questa funzione è praticamente indipendente dalla libreria, dovrebbe funzionare in qualsiasi linguaggio simile al C con sintassi simile.


Wow! Ho pensato che non avrei mai avuto una risposta Java! Capito grazie! E, come bonus, ha battuto alcune risposte e ha ottenuto lo swag extra! ₊₁
RudolfJelin

n==0può essere abbreviato n<1e anche n==1inn<2
AlexRacer

2

Haskell, 52 byte per rientro scheda 42 byte + swag extra

Modifica: salvato 10 byte grazie a @WChargin

Una funzione curry diadica - il primo argomento è il numero di dimensioni, il secondo è il raggio della n-palla.

v 0 r=1
v 1 r=2*r
v n r=2*pi*r*r*v(n-2)r/n

Formula ricorsiva per il volume di una palla n: V n = (2πr 2 V n-2 )n

Salvalo come file di script separato ed eseguilo con GHCi, con una funzione per il test vdell'output, ad es.show (v 3 4.5) . Non ho provato questo, per favore fatemi sapere se non funziona.

Vecchio programma con approssimazione 6.2832 per 2π sostituito (50 byte con rientro di tabulazione):

let v 0 r=1
    v 1 r=2*r
    v n r=2*pi*r*r*(v(n-2)r)/n

Questo può essere usato con GHCi in modalità multilinea (usando :set +mo racchiudendo il codice tra :{& :}, i contenitori si trovano sulla propria linea. È richiesta la funzione tester.

La tipizzazione statica con l'inferenza del tipo di programma completo entra in gioco qui, consentendo a Haskell di fare molto meglio di Scala, e avvicinandosi a Groovy, ma non battendolo del tutto grazie alla combinazione di schemi anziché a un ternario, che comporta una ripetizione del personaggio.


51 se si utilizza direttamente il layout, 49 se si sostituisce 2*piper 6.2832, e 47 se si elimina le parentesi intorno alla chiamata ricorsiva: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin

... ma il punteggio più tipico è l'invio come file di script separato; rilasciare let{}e sostituire i punti e virgola con gli avanzamenti di riga per ottenere solo 42 byte (senza trascinare la nuova riga).
wchargin,

@WChargin Sto imparando Haskell da 2 giorni interi, quindi grazie per i suggerimenti. Ho sbagliato con cautela tra parentesi perché non sono sicuro della precedenza tra operatore e funzione in Haskell
Tamoghna Chowdhury

2

Racket 69 byte (più swag extra)

Utilizza la formula ricorsiva da https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball§ion=3#Recursions

Compresi i suggerimenti di @wchargin

(define(v d r)(match d[0 1][1(* 2 r)][_(/(* 2 pi r r(v(- d 2)r))d)]))

Ungolfed (v = volume, d = dimensioni, r = raggio):

(define(v d r)
  (match d
    [0 1]
    [1 (* 2 r)]
    [_ (/ (*  2   pi   r   r   (v (- d 2) r)  )
          d)]
    ))

test:

(v 1 1)
(v 2 3)
(v 3 1)
(v 3 4.5)
(v 1 9.379)
(v 0 48)

Produzione:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1

Dubito fortemente che ciò sia legittimo: stai usando la funzione ricorsiva senza contare la sua definizione nel conteggio dei byte. Cioè, l'espressione che stai calcolando come 67 byte non è valida Racket, poiché vnon è associata (per non parlare degli altri parametri). Sicuramente devi contare anche tu (define(v d r))? Questo ti porta fino a 82 byte ...
wchargin

... ma puoi eliminare quattro byte da quello sostituendo il tuo condcon ifespressioni nidificate , portandoti giù a 78 byte con (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin,

... e radine altri tre usando a matchper ottenere (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin,

Grazie per ottimi suggerimenti. Includo questi nella risposta.
anche il

@wchargin: Ho potuto ridurre altri 9 byte riposizionando (v (- d 2) r) nella formula e usando solo "r r" invece di "(* rr)" poiché è già in una formula di moltiplicazione.
anche l'

1

Perl, 63 byte + swag extra

@a=1..2;push@a,6.283/$_*@a[$_-2]for 2..($b=<>);say$a[$b]*<>**$b

Accetta due numeri interi ner r, uno alla volta, quindi emette il volume n per il raggio dato r di una sfera n. Quando n = 0, V = 1 e quando n = 1, V = 2r. Tutte le ulteriori dimensioni sono calcolate con la seguente formula:

Recursive volume formula

Dal r n è il fattore del raggio in ogni formula, lo lascio fuori dal calcolo di base e lo applico solo alla fine.

2π è approssimato nel codice con 6.283.


Bello e ricorsivo, e ₊₁ per mostrare la formula ricorsiva.
RudolfJelin,

1

Scala, 53 byte

{import math._;(n,r)=>pow(r,n)*Seq(1,2,Pi,Pi*4/3)(n)}

Siamo spiacenti, niente swag extra per me :(

Spiegazione:

{                     //define a block, the type of this is the type of the last expression, which is a function
  import math._;        //import everything from math, for pow and pi
  (n,r)=>               //define a function
    pow(r,n)*             //r to the nth power multiplied by
    Seq(1,2,Pi,Pi*4/3)(n) //the nth element of a sequence of 1, 2, Pi and Pi*4/3
}

1

JavaScript (ES6), 39 byte, nessuno swag

(n,r)=>[1,r+r,a=Math.PI*r*r,a*r*4/3][n]

1

Python 3, 76 72 68 byte + swag extra!

Soluzione ricorsiva con swag extra!
Restituisce 0pern=0

from math import*
f=lambda n,r:n*r*2*(n<2or pi*r/n/n*(f(n-2,r)or 1))

Vecchio approccio ( 1per n=1):

from math import*
f=lambda n,r:1*(n<1)or r*2*(n<2)or 2*pi*r*r/n*f(n-2,r)

Formula ricorsiva da Wikipedia .

Provalo online.



1

Scala, 81 79 byte + swag extra!

Modifica: salvato 2 byte grazie a @AlexRacer

Una funzione diadica - il primo argomento è il numero di dimensioni, il secondo è il raggio della palla n.

def v(n:Int,r:Float):Float=if n<1 1 else if n<2 2*r else 6.2832f*r*r*v(n-2,r)/n

Formula ricorsiva per il volume di una palla n : V n = (2πr 2 V n-2 )n

La mancanza di inferenza di tipo di Scala per i tipi di ritorno di funzioni ricorsive e parametri di funzione e sintassi ternaria dettagliata fa un bel po 'qui :(


1

Groovy, 49 47 byte + swag extra!

Modifica: salvato 2 byte grazie a @AlexRacer

Una funzione diadica - il primo argomento è il numero di dimensioni, il secondo è il raggio della palla n.

def v(n,r){n<1?1:n<2?2*r:6.2832*r*r*v(n-2,r)/n}

Formula ricorsiva per il volume di una palla n: V n = (2πr 2 V n-2 )n

Digitazione dinamica FTW!

Le mie risposte Scala e Java utilizzano la stessa logica, ma con la digitazione statica quindi conteggi di byte più elevati a causa delle annotazioni sui tipi :(. Tuttavia, Scala e Groovy mi consentono di omettere returnil punto e virgola, in modo che il conteggio dei byte sia utile, diversamente da Java / C ...


₊₁ per lo SWAG extra!
RudolfJelin,

1

Lithp , 96 caratteri + swag extra

Linea divisa in 2 per leggibilità:

#N,R::((if (< N 2) ((? (!= 0 N) (* 2 R) 1)) ((/ (* (* (* (* (f (- N 2) R) 2)
        3.1416) R) R) N))))

Pensando di dover aggiornare il mio parser per richiedere meno spazi. La dimensione del codice verrebbe ridotta bene, specialmente in quella ((/ (* (* (* (*sezione.

Uso:

% n-circle.lithp
(
    (def f #N,R::((if (< N 2) ((? (!= 0 N) (* 2 R) 1)) ((/ (* (* (* (* (f (- N 2) R) 2) 3.1416) R) R) N)))))
    (print (f 1 1))
    (print (f 2 3))
    (print (f 3 1))
    (print (f 3 4.5))
    (print (f 1 9.379))
    (print (f 0 48))
)

#./run.js n-circle.lithp
2
28.274333882308138
4.1887902047863905
381.7035074111598
18.758
1

Grazie a Rudolf per aver rasato qualche byte.


1
Che ne dite di accorciare " 3.141592653589793" a " 3.1416", salvando 11 byte e ancora adattandosi alle regole?
RudolfJelin

1

CJam (27 byte con credito extra)

{1$_[2dP]*<f*\,:)-2%./1+:*}

Suite di test online . Questo è un blocco (funzione) anonimo che accetta argomentid r nello stack e lascia il risultato nello stack.

Dissezione

La formula generale n-dimensionale può essere riscritta come

2d2πd2rdd!!
{            e# Begin block: stack holds d r
  1$_[2dP]*< e#   Build a list which repeats [2 pi] d times and take the first d elements
  f*         e#   Multiply each element of the list by r
  \,:)-2%    e#   Build a list [1 ... d] and take every other element starting at the end
  ./         e#   Pointwise divide. The d/2 elements of the longer list are untouched
  1+:*       e#   Add 1 to ensure the list is non-empty and multiply its elements
}
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.