Círculos N-dimensionales!

16

Escribe un programa que tome dos números como entrada. El primero es el número de dimensiones: 0 para un punto, 1 para una línea recta, 2 para un círculo, 3 para una esfera. El segundo número es el radio del objeto o, si es unidimensional, el número mismo. Salida 0 para 0 dimensiones. La salida es la longitud / área / volumen del objeto.

Si llamamos al primer número n, al segundo ry a la salida x, obtenemos que:

  • para n = 0, x = 1

  • para n = 1, x = 2 × r

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

  • para n = 3, x = ( 4 / 3 ) x r 3 × π

  • y así sucesivamente ... si quieres, sin embargo.

Notas:

  • Los casos en que uno o ambos números son negativos, o cuando el primer número no es entero, no necesitan ser cubiertos.

  • El programa no debe leer de ningún archivo y la única entrada son esos dos números.

  • La salida debe usar solo números (por ejemplo, no "14 * pi") y debe tener una precisión de al menos dos dígitos decimales.

  • En cuanto a n = 0, puede generar 0 si acorta el código.

  • ¡Botín extra para una respuesta que cubre incluso 4 "esferas" y más dimensionales!

  • Es , por lo que gana la respuesta más corta en bytes.

Ejemplos:

 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
fuente
2
¡Hurra! ¡Me encantan las ecuaciones falsas de MathJax en las publicaciones!
RudolfJelin el
1
No es para criticar, pero no veo cómo una línea puede considerarse como un círculo 1d ...
xem
10
@xem Considere un círculo como todos los puntos que están dentro de una distancia dada del centro
Luis Mendo
3
Los tipos matemáticos llamarían a estas "bolas" de varias dimensiones. El conjunto de puntos con distancia desde el origen == res la esfera, el conjunto de puntos con distancia desde el origen <= res la bola. Entonces estos son 0 bolas = punto, 1 bola = segmento, 2 bolas = disco, 3 bolas = bola, 4 bolas, 5 bolas, etc. c. (aparece como " n-ball = nombre común").
Eric Towers el
3
"Salida 0 para 0 dimensiones" y "para n = 0, x = 1" se contradicen entre sí. ¿Podría elegir uno (o aclarar que ambos están permitidos)?
Paŭlo Ebermann el

Respuestas:

7

Jalea , 13 bytes + botín extra

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

Pruébalo en línea!

Funciona para cualquier dimensión, siempre que el valor fijo de π producido por ØP( 3.141592653589793) sea lo suficientemente preciso.

¿Cómo?

÷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
fuente
1
¡Bien hecho por vencer a Mathematica!
CJ Dennis
¡Felicidades, ganaste!
RudolfJelin
13

Mathematica, 18 bytes, hasta ~ 168.15 billones de dimensiones

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

Función anónima. Toma dos números como entrada y devuelve un número inexacto como salida. Funciona con cualquier cantidad de dimensiones. Salidas 1.para n = 0. Utiliza la fórmula del Volumen de una bola n en Wikipedia.

Explicación

Estamos intentando calcular π n / 2 / Γ ( n / 2 + 1) · R n , o N[Pi^(n/2)/Gamma[n/2 + 1] R^n]en Mathematica. En nuestro caso, #(primer argumento) es n y #2(segundo argumento) es R . Esto nos deja N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, que se pueden jugar de la siguiente manera:

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

y así, nuestro programa original.

LegionMammal978
fuente
Buena respuesta: ¡eso fue rápido! Solo para aclarar: ¿a cuántos dígitos es correcta la salida? ¿Cuántas dimensiones es posible calcular?
RudolfJelin
@ RudolfL.Jelínek Produce alrededor de 5 cifras significativas, y funciona para todos n hasta 168,146,894,169,516 para r = 1 (aunque con menos cifras).
LegionMammal978
@ LegionMammal978, ¿qué fórmula? Estoy bastante seguro de que no usa la función gamma allí
Angs
@Angs n ! = Γ  (  n + 1).
LegionMammal978
2
Oh, también !funciona para no integrales. Usar Mathematica para esto casi se siente como hacer trampa ... :)
Angs
6

JavaScript (ES6), 45 bytes + botín adicional

La fórmula recursiva de wikipedia debería funcionar para cualquier cantidad de dimensiones

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

R, 75 40 38 bytes (más botín adicional)

Bueno, parece que podría jugar al golf cediendo y usando la función gamma en lugar de las funciones recursivas.

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

Define una función anónima para calcular el volumen de una nhiperesfera de radio tridimensional r.

Algunos ejemplos:

1 1 -> 2

0 48 -> 1

2 3 -> 28.27433

3 4.5 -> 381.7035

7 7 -> 3891048

100 3 -> 122051813

Solución sin botín, 38 34 bytes

Por unos pocos bytes menos, puede tener una función anónima que solo funciona para las dimensiones 1 a 3. Devuelve numeric(0)para n=0y NApara n>3. ( numeric(0)es un vector numérico de longitud 0; NAes para "no disponible".) El rendimiento es idéntico a la solución general anterior.

function(n,r)c(1,pi,4/3*pi)[n]*r^n
rturnbull
fuente
1
₊₁ para el SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin
5

Haskell, 74 65 36 bytes + botín extra

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

La fórmula recursiva funciona para todas las dimensiones que se pueden presentar exactamente como un número de coma flotante de doble precisión, pero se repetirá infinitamente para las dimensiones no integrales. La versión anterior por el bien de la posterioridad:

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

Funciona para todas las dimensiones. Utiliza la fórmula del manifiesto tau . product[n,n-2..1.1]es un hack factorial doble que no contará cero paran==2

Angs
fuente
5

JavaScript, 61 51 49 43 bytes

0-3 dimensiones son compatibles porque no hay 4ta dimensión .

Gracias a @Hedi por guardar 7 bytes

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

Crea función d. Luego sube ra la npotencia th y luego la multiplica con un número dependiendo del nuso de operadores ternarios. Salidas 1paran=0

Da salida a al menos 2 decimales (10+ dp)

Aquí hay un fragmento de merienda!

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
fuente
Batir mi solución no publicada por ... por mucho. +1!
RudolfJelin
66
qué video más tonto ...
Nombre para mostrar el
1
@SargeBorsch Al menos eso demuestra mi punto :)
Kritixi Lithos
2
@SargeBorsch Jaja sí video tonto - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- En ese momento parece estar diciendo que hay una 4ta dimensión, ¡pero no 1ra, 2da o 3ra!
Level River St el
1
@LevelRiverSt Bueno, ese fue el primer resultado que estaba en la web ¯ \ _ (ツ) _ / ¯
Kritixi Lithos el
3

MATL , 17 bytes

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

Esto funciona solo hasta 3 dimensiones. Las entradas están en orden inverso, es decir:, rentonces n.

Pruébalo en línea!

Considere r=3, n=2como un ejemplo.

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
fuente
2

Java / C / C ++ / C #, 69 67 bytes + botín extra!

Editar: Guardado 2 bytes gracias a @AlexRacer

Una función diádica: el primer argumento es el número de dimensiones, el segundo es el radio de la bola n.

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

Fórmula recursiva para el volumen de una bola n: V n = (2πr 2 V n-2 )n

Whoa! ¡Java (mi lenguaje de prueba) supera a Scala aquí, gracias a la ?:sintaxis ternaria! Esta función es sintácticamente correcta en los 4 idiomas del encabezado, y la he probado con C (MinGW GCC 5.4.0) y C # (VS Ultimate 2016, C # 6.0). Supongo que también funcionará en C ++, así que allí. Como esta función es bastante independiente de la biblioteca, debería funcionar en cualquier lenguaje tipo C con una sintaxis similar.

Tamoghna Chowdhury
fuente
¡Guauu! ¡Pensé que nunca obtendría una respuesta de Java! ¡Gracias! Y, como beneficio adicional, superó algunas respuestas y obtuvo el botín extra. ₊₁
RudolfJelin
n==0se puede acortar n<1y también n==1an<2
AlexRacer
2

Haskell, 52 bytes para sangría de pestaña 42 bytes + botín adicional

Editar: guardado 10 bytes gracias a @WChargin

Una función curry diádica: el primer argumento es el número de dimensiones, el segundo es el radio de la bola n.

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

Fórmula recursiva para el volumen de una bola n: V n = (2πr 2 V n-2 )n

Guardar esto como un archivo separado guión y carrera con GHCi, con una función para probar vpara la salida, por ejemplo, show (v 3 4.5). No probé esto, avíseme si esto no funciona.

Programa anterior con una aproximación de 6.2832 para 2π reemplazados (50 bytes con sangría de tabulación):

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

Esto se puede usar con GHCi en modo multilínea (usando :set +mo encerrando el código entre :{& :}, los gabinetes están en sus propias líneas. Se requiere la función de prueba.

Aquí entra en juego la escritura estática con inferencia de tipo de programa completo, lo que permite a Haskell hacerlo mucho mejor que Scala, y se acerca a Groovy, pero no lo supera gracias a la coincidencia de patrones en lugar de un ternario, que implica cierta repetición de caracteres.

Tamoghna Chowdhury
fuente
51 si se utiliza directamente la disposición, de 49 años si se sustituye 2*pipor 6.2832, y 47 si se le cae el paréntesis alrededor de la llamada recursiva: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin
... pero la puntuación más típica es enviarla como un archivo de script separado; suelte let{}y reemplace mis puntos y comas con saltos de línea para obtener solo 42 bytes (sin arrastrar nueva línea).
wchargin
@WChargin He estado aprendiendo Haskell durante 2 días completos, así que gracias por los consejos. Erré por precaución con los paréntesis ya que no estoy seguro acerca de la precedencia de llamada de operador frente a función en Haskell
Tamoghna Chowdhury
2

Raqueta 69 bytes (más botín extra)

Utiliza una fórmula recursiva de https://en.wikipedia.org/w/index.php?title=Volume_of_an_n-ball§ion=3#Recursions

Incluyendo sugerencias de @wchargin

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

Sin golf (v = volumen, d = dimensiones, r = radio):

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

Pruebas:

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

Salida:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1
rnso
fuente
Dudo mucho que esto sea legítimo: está utilizando la función recursiva sin contar su definición en el recuento de bytes. Es decir, la expresión que está anotando como 67 bytes no es válida Racket, ya vque no está consolidada (sin mencionar los otros parámetros). ¿Seguramente necesitas contar (define(v d r))también? Esto le trae hasta 82 bytes ...
wchargin
... pero puede eliminar cuatro bytes de eso reemplazando su condcon ifexpresiones anidadas , reduciéndolo a 78 bytes con (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin
... y afeita tres más usando a matchpara obtener (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin
Gracias por las buenas sugerencias. Estoy incluyendo estos en la respuesta.
rnso
@wchargin: podría reducir 9 bytes más al reposicionar (v (- d 2) r) en la fórmula y usar solo "r r" en lugar de "(* rr)" ya que ya está en una fórmula de multiplicación.
rnso
1

Perl, 63 bytes + botín extra

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

Acepta dos enteros n y r, uno a la vez, luego genera el volumen n para un radio dado r de una esfera n. Cuando n = 0, V = 1, y cuando n = 1, V = 2r. Todas las dimensiones adicionales se calculan mediante la siguiente fórmula:

Fórmula de volumen recursivo

Desde r n es el factor del radio en cada fórmula, lo dejo fuera del cálculo base y solo lo aplico al final.

2π se aproxima en el código por 6.283.

Gabriel Benamy
fuente
Agradable y recursivo, y ₊₁ para mostrar la fórmula recursiva.
RudolfJelin el
1

Scala, 53 bytes

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

Lo siento, no hay botín extra para mí :(

Explicación:

{                     //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
fuente
1

JavaScript (ES6), 39 bytes, sin botín

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

Python 3, 76 72 68 bytes + botín extra!

¡Solución recursiva con botín extra!
Devoluciones 0paran=0

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

Enfoque antiguo ( 1para 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)

Fórmula recursiva de Wikipedia .

Pruébalo en línea.

pajonk
fuente
1

Scala, 81 79 bytes + botín extra!

Editar: Guardado 2 bytes gracias a @AlexRacer

Una función diádica: el primer argumento es el número de dimensiones, el segundo es el radio de la bola 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

Fórmula recursiva para el volumen de una bola n: V n = (2πr 2 V n-2 )n

La falta de inferencia de tipos de Scala para los tipos de retorno de funciones recursivas y parámetros de función y sintaxis ternaria detallada duele bastante aquí :(

Tamoghna Chowdhury
fuente
1

Groovy, 49 47 bytes + botín extra!

Editar: Guardado 2 bytes gracias a @AlexRacer

Una función diádica: el primer argumento es el número de dimensiones, el segundo es el radio de la bola n.

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

Fórmula recursiva para el volumen de una bola n: V n = (2πr 2 V n-2 )n

Typing dinámico FTW!

Mis respuestas de Scala y Java usan la misma lógica, pero con el tipeo estático, un recuento de bytes más alto debido a anotaciones de tipo :(. Sin embargo, Scala y Groovy me permiten omitir el returny el punto y coma, por lo que ayuda al recuento de bytes, a diferencia de Java / C ...

Tamoghna Chowdhury
fuente
₊₁ por el SWAG extra!
RudolfJelin el
1

Lithp , 96 caracteres + botín extra

Línea dividida en 2 para facilitar la lectura:

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

Pensando que necesito actualizar mi analizador para requerir menos espacios. El tamaño del código se reduciría muy bien, especialmente en esa ((/ (* (* (* (*sección.

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

Gracias a Rudolf por recortar unos pocos bytes.

Andrakis
fuente
1
¿Qué hay de acortar " 3.141592653589793" a " 3.1416", guardar 11 bytes y seguir encajando en las reglas?
RudolfJelin
1

CJam (27 bytes con crédito adicional)

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

Conjunto de pruebas en línea . Este es un bloque anónimo (función) que toma argumentosd r en la pila y deja el resultado en la pila.

Disección

La fórmula general n-dimensional se puede reescribir como

2re2πre2rrere!!
{            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
fuente