Círculos N-dimensionais!


16

Escreva um programa que aceite dois números como entrada. A primeira é o número de dimensões - 0 para um ponto, 1 para uma linha reta, 2 para um círculo, 3 para uma esfera. O segundo número é o raio do objeto ou, se é unidimensional, o próprio número. Saída 0 para 0 dimensões. A saída é o comprimento / área / volume do objeto.

Se chamarmos o primeiro número n, o segundo re a saída x, obtemos o seguinte:

  • para n = 0, x = 1

  • para n = 1, x = 2 × r

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

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

  • e assim por diante ... se você quiser, no entanto.

Notas:

  • Casos em que um ou ambos os números são negativos ou quando o primeiro número não é inteiro, não precisam ser cobertos.

  • O programa não deve ler nenhum arquivo e a única entrada são esses dois números.

  • A saída deve usar apenas números (por exemplo, não "14 * pi") e deve ter precisão de pelo menos dois dígitos decimais.

  • Quanto a n = 0, você pode gerar 0 se ele diminuir o código.

  • Ganhos extras por uma resposta que abrange até 4 "esferas" dimensionais e mais!

  • É , então a resposta mais curta em bytes vence!

Exemplos:

 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
Yay! Eu amo equações MathJax falsas em posts!
precisa saber é o seguinte

1
Não crítico, mas eu não vejo como uma linha pode ser considerado como um círculo 1d ...
xem

10
@xem Considere um círculo como todos os pontos que estão dentro de uma determinada distância do centro
Luis Mendo

3
Os tipos matemáticos chamariam essas "bolas" de várias dimensões. O conjunto de pontos com distância da origem == ré a esfera, o conjunto de pontos com distância da origem <= ré a bola. Então, são 0 bola = ponto, 1 bola = segmento, 2 bola = disco, 3 bola = bola, 4 bolas, 5 bolas, etc. (listado como " n-ball = nome comum").
Eric Towers

3
"Saída 0 para 0 dimensões" e "para n = 0, x = 1" se contradizem. Você poderia escolher um (ou esclarecer que ambos são permitidos)?
Paŭlo Ebermann 6/11/16

Respostas:


7

Gelatina , 13 bytes + ganhos extras

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

Experimente online!

Funciona para qualquer dimensão, desde que o valor fixo de π gerado por ØP( 3.141592653589793) seja suficientemente preciso.

Quão?

÷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
Muito bem por vencer o Mathematica!
CJ Dennis

Parabéns, você ganhou!
RudolfJelin

13

Mathematica, 18 bytes, até ~ 168,15 trilhões de dimensões

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

Função anônima. Pega dois números como entrada e retorna um número inexato como saída. Funciona com qualquer número de dimensões. Saídas 1.para n = 0. Usa a fórmula do Volume de um n-ball na Wikipedia.

Explicação

Estamos tentando calcular π n / 2 / Γ ( n / 2 + 1) · R n ou N[Pi^(n/2)/Gamma[n/2 + 1] R^n]no Mathematica. No nosso caso, #(primeiro argumento) é N e #2(segundo argumento) é R . Isso nos deixa com N[Pi^(#/2)/Gamma[#/2 + 1] #2^#] &, que pode ser jogado da seguinte maneira:

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 assim, nosso programa original.


Boa resposta - isso foi rápido! Apenas para esclarecimento: Para quantos dígitos a saída está correta? Quantas dimensões é possível calcular?
RudolfJelin

@ RudolfL.Jelínek Ele gera cerca de 5 números significativos e funciona para todos os n até 168.146.894.169.516 para r = 1 (embora com menos números).
precisa

@ LegionMammal978 que fórmula? Estou certo de que você não usa a função gama lá.
Angs 05/11

@Angs n ! = Γ  (  n + 1).
precisa

2
Ah, também !funciona para não integrais. Usando Mathematica para este quase se sente como fazer batota ... :)
Angs

6

JavaScript (ES6), 45 bytes + ganhos extras

A fórmula recursiva da wikipedia deve funcionar para qualquer número de dimensões

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

6

R, 75 40 38 bytes (mais ganhos adicionais)

Bem, parece que eu poderia resolver isso cedendo e usando a função gama em vez de funções recursivas.

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

Define uma função anônima para calcular o volume de uma nhiperesfera de raio tridimensional r.

Alguns exemplos:

1 1 -> 2

0 48 -> 1

2 3 -> 28.27433

3 4,5 -> 381,7035

7 7 -> 3891048

100 3 -> 122051813

Solução Swagless, 38 34 bytes

Por menos bytes, você pode ter uma função anônima que funciona apenas para as dimensões de 1 a 3. Retorna numeric(0)para n=0e NApara n>3. ( numeric(0)é um vetor numérico de comprimento 0; NAé para "não disponível".) O desempenho é idêntico à solução geral acima.

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

1
₊₁ para o SSSSSWWWWWAAAAAAAGGGGGGGGGG!
RudolfJelin

5

Haskell, 74 65 36 bytes + ganhos adicionais

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

Fórmula recursiva, funciona para todas as dimensões que podem ser apresentadas exatamente como um número de ponto flutuante de precisão dupla, mas fará um loop infinito para dimensões não integrais. A versão antiga por causa da posterioridade:

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

Funciona para todas as dimensões. Usa a fórmula do manifesto tau . product[n,n-2..1.1]é um truque fatorial duplo que não conta zero paran==2


5

JavaScript, 61 51 49 43 bytes

0-3 dimensões são suportadas porque não há quarta dimensão .

Obrigado a @Hedi por salvar 7 bytes

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

Cria função d. Em seguida, aumenta rpara a npotência th e multiplica-a com um número, dependendo do nuso de operadores ternários. Saídas 1paran=0

Dá saída a pelo menos 2 casas decimais (10+ dp)

Aqui está um trecho de lanche!

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>


Bata minha solução não postada por ... por muito. +1!
RudolfJelin

6
que vídeo idiota…
Nome para exibição

1
@SargeBorsch Pelo menos isso prova meu ponto :)
Kritixi Lithos

2
@SargeBorsch Haha yup video burro - 0:40 3 dimensions that behave in the same way and one that behaves in a different way- Nesse ponto, ele parece estar dizendo que há uma quarta dimensão, mas não a 1ª, 2ª ou 3ª!
Level River St

1
@LevelRiverSt Bem, esse foi o primeiro resultado em que estive na web ¯ \ _ (ツ) _ / ¯ #
Kritixi Lithos

3

MATL , 17 bytes

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

Isso funciona até 3 dimensões apenas. As entradas estão na ordem inversa, ou seja:, rentão n.

Experimente online!

Considere r=3, n=2como um exemplo.

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 bytes + ganhos extras!

Editar: salvou 2 bytes graças a @AlexRacer

Uma função diádica - o primeiro argumento é o número de dimensões, o segundo é o raio da 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 o volume de uma bola n: V n = (2πr 2 V n-2 )n

Uau! Java (minha linguagem de teste) vence o Scala aqui, graças à ?:sintaxe ternária concisa ! Esta função está sintaticamente correta nos 4 idiomas do cabeçalho e a testei com C (MinGW GCC 5.4.0) e C # (VS Ultimate 2016, C # 6.0). Estou assumindo que ele funcionará em C ++ também, então está aí. Como essa função é praticamente independente da biblioteca, deve funcionar em qualquer linguagem semelhante a C com sintaxe semelhante.


Uau! Eu pensei que nunca iria obter uma resposta Java! Entendi - obrigado! E, como um bônus, ele bateu algumas respostas e recebeu os ganhos extras! ₊₁
RudolfJelin

n==0pode ser encurtado para n<1e também n==1paran<2
AlexRacer

2

Haskell, 52 bytes para recuo da tabulação 42 bytes + ganhos extras

Editar: salvou 10 bytes graças a @WChargin

Uma função curada diádica - o primeiro argumento é o número de dimensões, o segundo é o raio da 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 o volume de uma bola n: V n = (2πr 2 V n-2 )n

Salve isso como um arquivo de script separado e execute com o GHCi, com uma função para testar va saída, por exemplo show (v 3 4.5),. Eu não testei isso, por favor me avise se isso não funcionar.

Programa antigo com aproximação 6.2832 para 2π substituído (50 bytes com recuo de tabulação):

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

Isso pode ser usado com o GHCi no modo de múltiplas linhas (usando :set +mou colocando o código entre :{& :}, os gabinetes estando em suas próprias linhas. É necessária a função de testador.

A digitação estática com inferência de tipo de programa completo entra em jogo aqui, permitindo que Haskell se saía muito melhor que Scala e se aproximando do Groovy, mas não superando isso graças à correspondência de padrões em vez de um ternário, envolvendo alguma repetição de caracteres.


51 se estiver usando o layout diretamente, 49 se você substituir 2*pipara 6.2832, e 47 se você deixar cair os parênteses em torno da chamada recursiva: let{v 0 r=1;v 1 r=2*r;v n r=2*pi*r*r*v(n-2)r/n}...
wchargin

… Mas a pontuação mais típica é enviar como um arquivo de script separado; solte o let{}e substitua meus pontos-e-vírgulas por feeds de linha para obter apenas 42 bytes (sem seguir a nova linha).
wchargin

@WChargin Estou aprendendo Haskell há dois dias, então obrigado pelos ponteiros. I errou no lado da cautela com os parênteses, como eu não tenho certeza sobre operador vs precedência chamada de função em Haskell
Tamoghna Chowdhury

2

Raquete 69 bytes (mais ganhos extras)

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

Incluindo sugestões de @wchargin

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

Sem golfe (v = volume, d = dimensões, r = raio):

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

Teste:

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

Resultado:

2
28.274333882308138
4.1887902047863905
381.7035074111599
18.758
1

Eu duvido muito que isso seja legítimo: você está usando a função recursiva sem contar sua definição na contagem de bytes. Ou seja, a expressão que você está marcando como 67 bytes não é uma raquete válida, pois vnão é vinculada (para não mencionar os outros parâmetros). Certamente você precisa contar (define(v d r))também? Isso gera até 82 bytes ...
wchargin 7/11/16

… Mas você pode eliminar quatro bytes substituindo-o condpor ifexpressões aninhadas , reduzindo-o para 78 bytes por (define(v d r)(if(= d 0)1(if(= d 1)(* 2 r)(*(/(* 2 pi(* r r))d)(v(- d 2)r))))).
wchargin

… E raspe mais três usando a matchpara obter (define(v d r)(match d[0 1][1(* 2 r)][_(*(/(* 2 pi(* r r))d)(v(- d 2)r))])).
wchargin

Obrigado por ótimas sugestões. Estou incluindo estes na resposta.
rnso

@ wchargin: eu poderia reduzir mais 9 bytes reposicionando (v (- d 2) r) na fórmula e usando apenas "r r" em vez de "(* rr)", pois já está em uma fórmula de multiplicação.
Rnso

1

Perl, 63 bytes + ganhos extras

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

Aceita dois números inteiros n e r, um de cada vez, e depois gera o volume n para o raio r dado de uma n esfera. Quando n = 0, V = 1 e quando n = 1, V = 2r. Todas as outras dimensões são calculadas pela seguinte fórmula:

Fórmula de volume recursivo

Como r n é o fator do raio em todas as fórmulas, deixo-o fora do cálculo base e só o aplico no final.

2π é aproximado no código por 6.283.


Agradável e recursivo e ₊₁ por mostrar a fórmula recursiva.
RudolfJelin

1

Scala, 53 bytes

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

Desculpe, nenhum ganho extra para mim :(

Explicação:

{                     //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 bytes, sem ganhos

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

1

Python 3, 76 72 68 bytes + ganhos extras!

Solução recursiva com ganhos extras!
Retorna 0paran=0

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

Abordagem antiga ( 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 da Wikipedia .

Experimente online.



1

Scala, 81 79 bytes + ganhos extras!

Editar: salvou 2 bytes graças a @AlexRacer

Uma função diádica - o primeiro argumento é o número de dimensões, o segundo é o raio da 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 o volume de uma bola n: V n = (2πr 2 V n-2 )n

A falta de inferência de tipo de Scala para tipos de retorno de funções recursivas e parâmetros de função e sintaxe ternária detalhada dói bastante aqui :(


1

Groovy, 49 47 bytes + ganhos extras!

Editar: salvou 2 bytes graças a @AlexRacer

Uma função diádica - o primeiro argumento é o número de dimensões, o segundo é o raio da 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 o volume de uma bola n: V n = (2πr 2 V n-2 )n

Digitação dinâmica FTW!

Minhas respostas Scala e Java usam a mesma lógica, mas com digitação estática, contagens de bytes mais altas devido às anotações de tipo :(. No entanto, Scala e Groovy me permitem omitir returno ponto e vírgula, de modo que ajude a contagem de bytes, ao contrário do Java / C ...


₊₁ para os ganhos extras!
RudolfJelin

1

Lithp , 96 caracteres + ganhos extras

Linha dividida em 2 para facilitar a leitura:

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

Pensando que preciso atualizar meu analisador para exigir menos espaços. O tamanho do código seria bem reduzido, especialmente nessa ((/ (* (* (* (*seção.

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

Agradecemos a Rudolf por remover alguns bytes.


1
Que tal encurtar " 3.141592653589793" para " 3.1416", salvar 11 bytes e ainda se encaixar nas regras?
precisa saber é o seguinte

1

CJam (27 bytes com crédito extra)

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

Conjunto de testes online . Este é um bloco anônimo (função) que recebe argumentosd r na pilha e deixa o resultado na pilha.

Dissecação

A fórmula n-dimensional geral pode ser reescrita como

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
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.