Cercles N-dimensionnels!

16

Écrivez un programme qui prend deux nombres en entrée. Le premier est le nombre de dimensions - 0 pour un point, 1 pour une ligne droite, 2 pour un cercle, 3 pour une sphère. Le deuxième nombre est le rayon de l'objet ou, s'il est unidimensionnel, le nombre lui-même. Sortie 0 pour 0 dimensions. La sortie est la longueur / surface / volume de l'objet.

Si nous appelons le premier numéro n, le second ret la sortie x, nous obtenons cela:

  • pour n = 0, x = 1

  • pour n = 1, x = 2 × r

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

  • pour n = 3, x = ( quatre / 3 ) × r 3 × π

  • et ainsi de suite ... si vous voulez, cependant.

Remarques:

  • Les cas où un ou les deux nombres sont négatifs, ou lorsque le premier nombre n'est pas entier, n'ont pas besoin d'être couverts.

  • Le programme ne doit lire aucun fichier et les seules entrées sont ces deux nombres.

  • La sortie doit utiliser uniquement des chiffres (par exemple pas "14 * pi") et doit être précise à au moins deux chiffres décimaux.

  • Quant à n = 0, vous pouvez sortir 0 s'il raccourcit le code.

  • Un butin supplémentaire pour une réponse couvrant même des "sphères" de 4 dimensions et plus!

  • C'est le de , donc la réponse la plus courte en octets gagne!

Exemples:

 1 1 -> 2

 2 3 -> 28,27

 3 1 -> 4,19

 3 4,5 -> 381,70

 1 9.379 -> 18.758

 0 48 -> 1
RudolfJelin
la source
2
Yay! J'adore les fausses équations MathJax dans les articles!
RudolfJelin
1
Pas pour critiquer, mais je ne vois pas comment une ligne peut être considérée comme un cercle 1d ...
xem
10
@xem Considérez un cercle comme tous les points qui sont à une distance donnée du centre
Luis Mendo
3
Les types mathématiques appellent ces "boules" de différentes dimensions. L'ensemble des points à distance de l'origine == rest la sphère, l'ensemble des points à distance de l'origine <= rest la balle. Alors ce sont 0-ball = point, 1-ball = segment, 2-ball = disque, 3-ball = ball, 4-ball, 5-ball, et c. (répertorié comme " n-ball = nom commun").
Eric Towers
3
"Sortie 0 pour 0 dimensions" et "pour n = 0, x = 1" se contredisent. Pourriez-vous s'il vous plaît en choisir un (ou préciser que les deux sont autorisés)?
Paŭlo Ebermann

Réponses:

7

Gelée , 13 octets + butin supplémentaire

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

Essayez-le en ligne!

Fonctionne pour n'importe quelle dimension, tant que la valeur fixe de π fournie par ØP(3.141592653589793 ) est suffisamment précise.

Comment?

÷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)
Jonathan Allan
la source
1
Bravo pour battre Mathematica!
CJ Dennis
Félicitations, vous avez gagné!
RudolfJelin
13

Mathematica, 18 octets, jusqu'à ~ 168,15 billions de dimensions

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

Fonction anonyme. Prend deux nombres en entrée et renvoie un nombre inexact en sortie. Fonctionne avec n'importe quel nombre de dimensions. Sorties 1.pour n = 0. Utilise la formule du volume d'une n-boule sur Wikipedia.

Explication

Nous essayons de calculer π n / 2 / Γ ( n / 2 + 1) · R n , ou N[Pi^(n/2)/Gamma[n/2 + 1] R^n]en Mathematica. Dans notre cas, #(premier argument) est n et #2(second argument) est R . Cela nous laisse avecN[Pi^(#/2)/Gamma[#/2 + 1] #2^#] & , qui peut être joué comme suit:

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

et donc, notre programme original.

LegionMammal978
la source
Belle réponse - c'était rapide! Juste pour clarification: à combien de chiffres la sortie est-elle correcte? Combien de dimensions est-il possible de calculer?
RudolfJelin
@ RudolfL.Jelínek Il produit environ 5 chiffres significatifs et fonctionne pour tous n jusqu'à 168.146.894.169.516 pour r = 1 (quoique avec moins de chiffres).
LegionMammal978
@ LegionMammal978 quelle formule? Je suis certain que vous n'utilisez pas la fonction gamma là
Angs
@Angs n ! = Γ  (  n + 1).
LegionMammal978
2
Oh, ça !marche aussi pour les non-intégrales. Utiliser Mathematica pour cela ressemble presque à de la triche… :)
Angs
6

JavaScript (ES6), 45 octets + swag supplémentaire

Formule récursive de wikipedia , devrait fonctionner pour n'importe quel nombre de dimensions

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

R, 75 40 38 octets (plus un swag supplémentaire)

Eh bien, on dirait que je pourrais jouer au golf en cédant et en utilisant la fonction gamma plutôt que les fonctions récursives.

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

Définit une fonction anonyme pour calculer le volume d'une nhypersphère dimensionnelle de rayon r.

Quelques exemples:

1 1 -> 2

0 48 -> 1

2 3 -> 28.27433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Solution sans swag, 38 34 octets

Pour quelques octets de moins, vous pouvez avoir une fonction anonyme qui ne fonctionne que pour les dimensions 1 à 3. Renvoie numeric(0)pour n=0et NApour n>3. ( numeric(0)est un vecteur numérique de longueur 0; NAest pour "non disponible".) Les performances sont par ailleurs identiques à la solution générale ci-dessus.

function(n,r)c(1,pi,4/3*pi)[n]*r^n
rturnbull
la source
1
₊₁ pour le SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin
5

Haskell, 74 65 36 octets + swag supplémentaire

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

Formule récursive, fonctionne pour toutes les dimensions qui peuvent être présentées exactement comme un nombre à virgule flottante double précision, mais bouclera à l'infini pour les dimensions non intégrales. L'ancienne version pour la postériorité:

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

Fonctionne pour toutes les dimensions. Utilise la formule du manifeste tau . product[n,n-2..1.1]est un hack factoriel double qui ne comptera pas zéro pourn==2

Angs
la source
5

JavaScript, 61 51 49 43 octets

Les dimensions 0-3 sont prises en charge car il n'y a pas de 4e dimension .

Merci à @Hedi pour avoir économisé 7 octets

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

Crée une fonction d. Augmente rensuite la npuissance e puis la multiplie par un nombre en fonction des nopérateurs ternaires. Sorties 1pourn=0

Donne la sortie à au moins 2 décimales (10+ dp)

Voici un extrait de collation!

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>

Kritixi Lithos
la source
Battre ma solution non publiée de ... par beaucoup. +1!
RudolfJelin
6
quelle stupide vidéo…
Nom d'affichage
1
@SargeBorsch Au moins, cela prouve mon point :)
Kritixi Lithos
2
@SargeBorsch Haha yup dumb video - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- À ce stade, il semble dire qu'il y a une 4ème dimension, mais pas de 1ère, 2ème ou 3ème!
Level River St
1
@LevelRiverSt Eh bien, c'était le premier résultat que j'étais sur le Web ¯ \ _ (ツ) _ / ¯
Kritixi Lithos
3

MATL , 17 octets

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

Cela fonctionne jusqu'à 3 dimensions seulement. Les entrées sont dans l'ordre inverse, c'est-à-dire:, ralors n.

Essayez-le en ligne!

Considérez r=3, n=2par exemple.

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
Luis Mendo
la source
2

Java / C / C ++ / C #, 69 67 octets + swag supplémentaire!

Edit: sauvé 2 octets grâce à @AlexRacer

Une fonction dyadique - le premier argument est le nombre de dimensions, le second est le rayon de la n-boule.

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

Formule récursive pour le volume d'une n-boule: V n = (2πr 2 V n-2 )n

Whoa! Java (mon langage de test) bat Scala ici, grâce à la ?:syntaxe ternaire laconique ! Cette fonction est syntaxiquement correcte dans les 4 langues de l'en-tête, et je l'ai testée avec C (MinGW GCC 5.4.0), et C # (VS Ultimate 2016, C # 6.0). Je suppose que cela fonctionnera également en C ++, donc là. Étant donné que cette fonction est à peu près indépendante de la bibliothèque, elle devrait fonctionner dans n'importe quel langage de type C avec une syntaxe similaire.

Tamoghna Chowdhury
la source
Hou la la! Je pensais que je n'aurais jamais de réponse Java! Je l'ai Merci! Et, en prime, il a battu certaines réponses et a obtenu le butin supplémentaire! ₊₁
RudolfJelin
n==0peut être raccourci à n<1et aussi n==1àn<2
AlexRacer
2

Haskell, 52 octets pour le retrait de tabulation 42 octets + swag supplémentaire

Edit: 10 octets enregistrés grâce à @WChargin

Une fonction cury dyadique - le premier argument est le nombre de dimensions, le second est le rayon de la n-boule.

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

Formule récursive pour le volume d'une n-boule: V n = (2πr 2 V n-2 )n

Save this as a separate script file and run with GHCi, with a function for testing v for output, e.g., show (v 3 4.5). I did not test this, please let me know if this doesn't work.

Old program with 6.2832 approximation for 2π replaced (50 bytes with tab indent):

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

This can be used with GHCi in multiline mode (using :set +m or enclosing the code between :{ & :}, the enclosures being on their own lines. Tester function required.

Static typing with full-program type inference comes into play here, allowing Haskell to do far better than Scala, and approaching Groovy, but not quite beating it thanks to the pattern match instead of a ternary, involving some character repetition.

Tamoghna Chowdhury
la source
51 if using layout directly, 49 if you substitute 2*pi for 6.2832, and 47 if you drop the parentheses around the recursive call: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}
wchargin
…but more typical scoring is to submit as a separate script file; drop the let{} and replace my semicolons with linefeeds to get just 42 bytes (without trailing newline).
wchargin
@WChargin I've been learning Haskell for a whole 2 days, so thanks for the pointers. I erred on the side of caution with the parentheses as I'm not sure about operator vs function call precedence in Haskell
Tamoghna Chowdhury
2

Racket 69 bytes (plus extra swag)

Uses recursive formula from https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball&section=3#Recursions

Including suggestions by @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=dimensions, r=radius):

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

Testing:

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

Output:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1
rnso
la source
Je doute fortement que cela soit légitime: vous utilisez la fonction récursive sans compter sa définition dans le nombre d'octets. Autrement dit, l'expression que vous marquez comme 67 octets n'est pas une raquette valide, comme elle vn'est pas liée (sans parler des autres paramètres). Vous devez sûrement compter (define(v d r))aussi? Cela vous amène à 82 octets…
wchargin
…but you can shave off four bytes from that by replacing your cond with nested if expressions, bringing you down to 78 bytes with (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin
…and shave off three more by using a match to get (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin
Thanks for great suggestions. I am including these in the answer.
rnso
@wchargin : I could reduce 9 more bytes by repositioning (v (- d 2) r) in formula and by using only "r r" instead of "(* r r)" since it is already in a multiplication formula.
rnso
1

Perl, 63 bytes + extra swag

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

Accepts two integers n and r, one at a time, then outputs the n-volume for given radius r of an n-sphere. When n = 0, V = 1, and when n = 1, V = 2r. All further dimensions are calculated by the following formula:

Recursive volume formula

Since rn is the radius's factor in every formula, I leave it out of the base calculation and only apply it at the end.

2π is approximated in the code by 6.283.

Gabriel Benamy
la source
Nice and recursive, and ₊₁ for showing the recursive formula.
RudolfJelin
1

Scala, 53 bytes

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

Sorry, no extra swag for me :(

Explanation:

{                     //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
}
corvus_192
la source
1

JavaScript (ES6), 39 bytes, no swag

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

Python 3, 76 72 68 bytes + extra swag!

Recursive solution with extra swag!
Returns 0 for n=0

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

Old approach (1 for 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)

Recursive formula from Wikipedia.

Try it online.

pajonk
la source
1

Scala, 81 79 bytes + extra swag!

Edit: Saved 2 bytes thanks to @AlexRacer

A dyadic function - first argument is number of dimensions, second is the radius of the n-ball.

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

Recursive formula for the volume of an n-ball: Vn=(2πr2Vn-2)n

Scala's lack of type inference for return types of recursive functions and function parameters and verbose ternary syntax hurts quite a bit here :(

Tamoghna Chowdhury
la source
1

Groovy, 49 47 bytes + extra swag!

Edit: Saved 2 bytes thanks to @AlexRacer

A dyadic function - first argument is number of dimensions, second is the radius of the n-ball.

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

Recursive formula for the volume of an n-ball: Vn=(2πr2Vn-2)n

Dynamic Typing FTW!

My Scala and Java answers use the same logic, but with static typing so higher byte counts due to type annotations :(. However, Scala and Groovy allow me to omit the return and the semicolon, so that helps the byte count, unlike Java/C...

Tamoghna Chowdhury
la source
₊₁ for the extra SWAG!
RudolfJelin
1

Lithp, 96 characters + extra swag

Line split in 2 for readability:

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

Thinking I need to upgrade my parser to require less spaces. Code size would be cut down nicely, especially in that ((/ (* (* (* (* section.

Usage:

% 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

Thanks to Rudolf for shaving a few bytes off.

Andrakis
la source
1
What about shortening "3.141592653589793" to "3.1416", saving 11 bytes and still fitting into the rules?
RudolfJelin
1

CJam (27 bytes with extra credit)

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

Online test suite. This is an anonymous block (function) which takes arguments d r on the stack and leaves the result on the stack.

Dissection

The general n-dimensional formula can be rewritten as

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
}
Peter Taylor
la source