Meios metálicos de alta precisão


13

fundo

Os meios metálicos , começando com a famosa média dourada , são definidos para todo número natural (número inteiro positivo), e cada um é uma constante irracional (possui uma expansão decimal infinita não recorrente).

Para um número natural , a média metálica é a raiz de uma equação quadrática

As raízes são sempre

mas a média metálica é geralmente dada como a raiz positiva. Portanto, para esta questão, será definido por:

Para o resultado é a famosa proporção áurea:


Desafio

Seu código deve receber 2 entradas: nep (a ordem não é importante desde que seja consistente)

  • n é um número natural que indica qual média metálica
  • p é um número natural que indica quantas casas decimais de precisão

Seu código deve gerar a enésima média metálica até p casas decimais de precisão.

Validade

Seu código é válido se funcionar com valores de n ep de 1 a 65.535.

Você deve gerar um decimal no formato

dígito (s) .dígito (s) (sem espaços)

Por exemplo, a média de ouro com 9 casas decimais é

1.618033988

Exiba o último dígito sem arredondamento, como apareceria em uma expansão decimal mais longa. O próximo dígito na média de ouro é 7, mas os 8 finais no exemplo não devem ser arredondados para 9.

O número de dígitos decimais deve ser p, o que significa que quaisquer zeros à direita também devem ser incluídos.

Respostas do formulário

não são válidos - você deve usar uma expansão decimal.

Você pode gerar até 1 nova linha inicial e até 1 nova linha final. Você não pode imprimir nenhum espaço ou qualquer outro caractere além dos dígitos e do ponto único / ponto final / período.

Ponto

Este é o código padrão de golfe: sua pontuação é o número de bytes no seu código.


Entre os melhores

(Usando o snippet do cabeçalho de Martin )

Respostas:


17

dc, 12

?kdd*4+v+2/p
  • ? Empurre n ep na pilha
  • k defina a precisão para p
  • dd duplicar n duas vezes (total de três cópias)
  • * multiplicar n * n
  • 4+ adicione 4
  • v pegue raiz quadrada
  • + add n (última cópia na pilha)
  • 2/ dividir por 2
  • p impressão

Caso de teste:

$ dc -f metalmean.dc <<< "1 9"
1.618033988
$

7
Ferramenta certa para o trabalho.
Dennis

5
@ Dennis seu tem que ser a primeira vez CJam é quase 3 vezes mais tempo que qualquer outra coisa ;-)
Digital Trauma

2

R, 116 bytes

library(Rmpfr);s=scan();n=mpfr(s[1],1e6);r=(n+(4+n^2)^.5)/2;t=toString(format(r,s[2]+2));cat(substr(t,1,nchar(t)-1))

Isso lê dois números inteiros de STDIN e imprime o resultado em STDOUT. Você pode experimentá-lo online .

Ungolfed + explicação:

# Import the Rmpfr library for arbitrary precision floating point arithmetic
library(Rmpfr)

# Read two integers from STDIN
s <- scan()

# Set n equal to the first input as an mpfr object with 1e6 bits of precision
n <- mpfr(s[1], 1e6)

# Compute the result using the basic formula
r <- (n + sqrt(4 + n^2)) / 2

# Get the rounded string representation of r with 1 more digit than necessary
t <- toString(format(r, s[2] + 2))

# Print the result with p unrounded digits
cat(substr(t, 1, nchar(t) - 1))

Se você não tiver a Rmpfrbiblioteca instalada, poderá install.packages("Rmpfr")e todos os seus sonhos se tornarão realidade.


1

Mathematica, 50 bytes

SetAccuracy[Floor[(#+Sqrt[4+#^2])/2,10^-#2],#2+1]&

Define uma função anônima que leva ne pem ordem. Eu uso Floorpara evitar o arredondamento SetAccuracy, o que eu preciso para obter uma saída decimal.


@ Arcinde Infelizmente, não posso usar números de precisão de máquinas, pois eles não seriam capazes de lidar p>15.
usar o seguinte código

1

CJam, 35 bytes

1'el+~1$*_2#2$2#4*+mQ+2/1$md@+s0'.t

p primeiro e depois n .

Experimente online no intérprete CJam .

Como funciona

Simplesmente calculamos a fórmula da pergunta para n × 10 p , obtemos a parte inteira e fracionária do resultado dividida por 10 p , preenchemos a parte fracionária com zeros à esquerda para obter dígitos p e imprima as partes separadas por um ponto.

1'e  e# Push 1 and 'e'.
l+   e# Read a line from STDIN and prepend the 'e'.
~    e# Evaluate. This pushes 10**p (e.g., 1e3 -> 1000) and n.
1$*  e# Copy 10**p and multiply it with n.
_2#  e# Copy n * 10**p and square it.
2$   e# Copy 10**p.
2#4* e# Square and multiply by 4.
+    e# Add (n * 10**p)**2 and 4 * 10**2p.
mQ   e# Push the integer part of the square root.
+2/  e# Add to n * 10**p and divide by 2.
1$md e# Perform modular division by 10**p.
@+s  e# Add 10**p to the fractional part and convert to string. 
0'.t e# Replace the first character ('1') by a dot.

1

Python 2, 92 bytes

Como agora estou olhando para as respostas, parece que a resposta CJam usa o mesmo método básico como este. Calcula a resposta n*10**pe depois adiciona o ponto decimal. É incrivelmente ineficiente devido ao modo como calcula a parte inteira da raiz quadrada (basta adicionar 1 até chegar lá).

n,p=input()
e=10**p;r=0
while(n*n+4)*e*e>r*r:r+=1
s=str((n*e+r-1)/2);print s[:-p]+'.'+s[-p:]

1

PHP, 85 78 bytes

echo bcdiv(bcadd($n=$argv[bcscale($argv[2])],bcsqrt(bcadd(4,bcpow($n,2)))),2);

Ele usa a extensão matemática BC Math que, em alguns sistemas, não pôde estar disponível. Ele precisa ser incluído no tempo de compilação , especificando a --enable-bcmathopção de linha de comando. Está sempre disponível no Windows e parece que também está incluído na versão PHP que acompanha o OSX.

Atualização :

Eu apliquei todos os hacks sugeridos pelo @blackhole em seus comentários (obrigado!), Depois apertei a inicialização $nno seu primeiro uso (mais 3 bytes salvos) e agora o código se encaixa em uma única linha na caixa de código acima.


@Blackhole. 85, de fato. Provavelmente li 86 (fiz uma seleção um pouco maior) e escrevi 68 por engano. Corrigido agora.
axiac

1
Sem problemas :). A propósito, você pode ter 1 byte a menos: remova os parênteses ao redor do echo, apenas deixe um espaço depois dele.
Blackhole

1
E como você espera bcscaleretornar true, você pode usar $n=$argv[bcscale($argv[2])];e salvar mais 2 bytes.
Blackhole

Isso é um bom truque.
axiac

A sujeira do código é uma arte: P. Ah, o último: em bcpow($n,2)vez de bcmul($n,$n)economizar 1 byte.
Blackhole

1

J, 27 bytes

4 :'}:":!.(2+x)-:y+%:4+*:y'

Explicação:

4 :'                      '   | Define an explicit dyad
                       *:y    | Square y
                     4+       | Add 4
                   %:         | Square root
                 y+           | Add y
               -:             | Half
      ":!.(2+x)               | Set print precision to 2+x
    }:                        | Remove last digit, to fix rounding

Chame assim:

    9 (4 :'}:":!.(2+x)-:y+%:4+*:y') 1
1.618033988

Outra solução um pouco mais fria:

4 :'}:":!.(2+x){.>{:p._1,1,~-y'

Que calcula as raízes do polinômio x ^ 2 - nx - 1. Infelizmente, a maneira como J formata o resultado torna a recuperação da raiz desejada um pouco mais longa.

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.