Medios Metálicos de Alta Precisión

13

Antecedentes

Las medias metálicas , comenzando con la famosa media dorada , se definen para cada número natural (entero positivo), y cada una es una constante irracional (tiene una expansión decimal infinita no recurrente).

Para un número natural , la media metálica es la raíz de una ecuación cuadrática

Las raíces son siempre

pero la media metálica generalmente se da como la raíz positiva. Entonces, para esta pregunta, se definirá por:

Para el resultado es la famosa proporción áurea:


Desafío

Su código debe tomar 2 entradas: n y p (el orden no es importante siempre que sea consistente)

  • n es un número natural que indica qué media metálica
  • p es un número natural que indica cuántos decimales de precisión

Su código debe generar la enésima media metálica con precisión de decimales p.

Validez

Su código es válido si funciona para valores de n y p de 1 a 65.535.

Debe generar un decimal en la forma

dígito (s) .digito (s) (sin espacios)

Por ejemplo, la media dorada a 9 decimales es

1.618033988

Muestra el último dígito sin redondear, ya que aparecería en una expansión decimal más larga. El siguiente dígito en la media dorada es un 7, pero el 8 final en el ejemplo no debe redondearse a un 9.

El número de dígitos decimales debe ser p, lo que significa que también se deben incluir los ceros finales.

Respuestas del formulario

no son válidos: debe usar una expansión decimal.

Puede generar hasta 1 nueva línea inicial y hasta 1 nueva línea final. No puede generar espacios ni ningún otro carácter además de los dígitos y el punto único / punto final / punto.

Puntuación

Este es el código estándar de golf: su puntaje es el número de bytes en su código.


Tabla de clasificación

(Usando el fragmento de la tabla de clasificación de Martin )

trichoplax
fuente

Respuestas:

17

dc, 12

?kdd*4+v+2/p
  • ? Empuja n y p sobre la pila
  • k establecer precisión a p
  • dd duplicar n dos veces (total tres copias)
  • * multiplicar n * n
  • 4+ agregar 4
  • v tomar raíz cuadrada
  • + agregar n (última copia en la pila)
  • 2/ dividir por 2
  • p impresión

Caso de prueba:

$ dc -f metalmean.dc <<< "1 9"
1.618033988
$
Trauma digital
fuente
77
Herramienta adecuada para el trabajo.
Dennis
55
@Dennis tiene que ser la primera vez que CJam es casi 3 veces más que otra cosa ;-)
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))

Esto lee dos enteros de STDIN e imprime el resultado en STDOUT. Puedes probarlo en línea .

Ungolfed + explicación:

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

Si no tiene la Rmpfrbiblioteca instalada, puede hacerlo install.packages("Rmpfr")y todos sus sueños se harán realidad.

Alex A.
fuente
1

Mathematica, 50 bytes

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

Define una función anónima que toma ny pen orden. Utilizo Floorpara evitar el redondeo SetAccuracy, que necesito para obtener una salida decimal.

Campeonato 2012
fuente
@Arcinde Desafortunadamente, no puedo usar números de precisión de máquina, ya que no podrían manejarlos p>15.
2012rcampion
1

CJam, 35 bytes

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

Lee p primero, luego n .

Pruébelo en línea en el intérprete de CJam .

Cómo funciona

Simplemente calculamos la fórmula de la pregunta para n × 10 p , obtenemos el número entero y la parte fraccional del resultado dividido por 10 p , rellenamos la parte fraccional con ceros a la izquierda para obtener dígitos p e imprimimos las partes separadas por un punto.

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.
Dennis
fuente
1

Python 2, 92 bytes

Como ahora estoy mirando las respuestas, parece que la respuesta de CJam usa el mismo método básico que este. Calcula la respuesta para n*10**py luego agrega el punto decimal. Es increíblemente ineficiente debido a la forma en que calcula la parte entera de la raíz cuadrada (solo sumando 1 hasta que llegue allí).

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:]
KSab
fuente
1

PHP, 85 78 bytes

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

Utiliza la extensión matemática BC Math que, en algunos sistemas, podría no estar disponible. Debe incluirse en el tiempo de compilación especificando la --enable-bcmathopción de línea de comando. Siempre está disponible en Windows y parece que también está incluido en la versión de PHP incluida con OSX.

Actualización :

Apliqué todos los hacks sugeridos por @blackhole en sus comentarios (¡gracias!) Luego exprimí la inicialización $nen su primer uso (3 bytes más guardados) y ahora el código cabe en una sola línea en el cuadro de código anterior.

axiac
fuente
@Blackhole. 85, de hecho. Probablemente leí 86 (hice una selección un poco más grande) y escribí 68 por error. Corregido ahora.
axiac
1
No hay problema :). Por cierto, puede tener 1 byte menos: elimine el paréntesis alrededor del echo, solo deje un espacio después.
Blackhole
1
Y como espera bcscaleregresar true, puede usar $n=$argv[bcscale($argv[2])];y guardar 2 bytes más.
Blackhole
Ese es un buen truco.
axiac
La suciedad del código es un arte: P. Oh, el último: en bcpow($n,2)lugar de bcmul($n,$n)ahorra 1 byte.
Blackhole
1

J, 27 bytes

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

Explicación:

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

Llámalo así:

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

Otra solución un poco más fría:

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

Que calcula las raíces del polinomio x ^ 2 - nx - 1. Desafortunadamente, la forma en que J formatea el resultado hace que retomar la raíz deseada un poco más.

Bolce Bussiere
fuente