Moyens métalliques de haute précision


13

Contexte

Les moyennes métalliques , à commencer par la fameuse moyenne d'or , sont définies pour chaque nombre naturel (entier positif), et chacune est une constante irrationnelle (elle a une expansion décimale non récurrente infinie).

Pour un nombre naturel , la moyenne métallique est la racine d'une équation quadratique

Les racines sont toujours

mais la moyenne métallique est généralement donnée comme racine positive. Donc, pour cette question, elle sera définie par:

Car le résultat est le fameux nombre d'or:


Défi

Votre code doit prendre 2 entrées: n et p (l'ordre n'est pas important tant qu'il est cohérent)

  • n est un nombre naturel indiquant quelle moyenne métallique
  • p est un nombre naturel indiquant le nombre de décimales de précision

Votre code doit afficher la nième moyenne métallique avec une précision de p décimales.

Validité

Votre code est valide s'il fonctionne pour des valeurs de n et p de 1 à 65 535.

Vous devez sortir une décimale sous la forme

chiffre (s). chiffre (s) (sans espaces)

Par exemple, le nombre d'or à 9 décimales est

1.618033988

Affichez le dernier chiffre sans arrondir, car il apparaîtrait dans une extension décimale plus longue. Le chiffre suivant du nombre d'or est un 7, mais le 8 final de l'exemple ne doit pas être arrondi à un 9.

Le nombre de chiffres décimaux doit être p, ce qui signifie que tous les zéros de fin doivent également être inclus.

Réponses du formulaire

ne sont pas valides - vous devez utiliser une extension décimale.

Vous pouvez générer jusqu'à 1 nouvelle ligne de début et jusqu'à 1 nouvelle ligne de fin. Vous ne pouvez pas afficher d’espaces ni d’autres caractères que les chiffres et le point unique / point final / période.

But

C'est du golf à code standard: votre score est le nombre d'octets dans votre code.


Classement

(En utilisant l'extrait de classement de Martin )

Réponses:


17

dc, 12

?kdd*4+v+2/p
  • ? Poussez n et p sur la pile
  • k définir la précision sur p
  • dd dupliquer n deux fois (trois copies au total)
  • * multiplier n * n
  • 4+ ajouter 4
  • v prendre racine carrée
  • + ajouter n (dernière copie sur la pile)
  • 2/ diviser par 2
  • p impression

Cas de test:

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

7
Le bon outil pour le travail.
Dennis

5
@Dennis c'est la première fois que CJam est presque 3 fois plus longue que quelque chose d'autre ;-)
Digital Trauma

2

R, 116 octets

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

Cela lit deux entiers de STDIN et imprime le résultat dans STDOUT. Vous pouvez l' essayer en ligne .

Non golfé + explication:

# 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 vous n'avez pas la Rmpfrbibliothèque installée, vous pouvez install.packages("Rmpfr")et tous vos rêves deviendront réalité.


1

Mathematica, 50 octets

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

Définit une fonction anonyme qui prend net pdans l'ordre. J'utilise Floorpour empêcher l'arrondi avec SetAccuracy, dont j'ai besoin pour obtenir une sortie décimale.


@Arcinde Je ne peux malheureusement pas utiliser les chiffres de précision de la machine, car ils ne pourraient pas les gérer p>15.
2012rcampion

1

CJam, 35 octets

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

Lit p d' abord, puis n .

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

Nous calculons simplement la formule de la question pour n × 10 p , obtenons la partie entière et fractionnaire du résultat divisé par 10 p , remplissons la partie fractionnaire avec des zéros de tête pour obtenir p chiffres et imprimons les parties séparées par un point.

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 octets

Comme je regarde maintenant les réponses, il semble que la réponse CJam utilise la même méthode de base que celle-ci. Il calcule la réponse pour n*10**ppuis ajoute la virgule décimale. Il est incroyablement inefficace en raison de la façon dont il calcule la partie entière de la racine carrée (en ajoutant simplement 1 jusqu'à ce qu'il y arrive).

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 octets

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

Il utilise l' extension mathématique BC Math qui, sur certains systèmes, ne pouvait pas être disponible. Il doit être inclus dans le temps de compilation en spécifiant l' --enable-bcmathoption de ligne de commande. Il est toujours disponible sur Windows et il semble qu'il soit également inclus dans la version PHP fournie avec OSX.

Mise à jour :

J'ai appliqué tous les hacks suggérés par @blackhole dans leurs commentaires (merci!) Puis j'ai pressé l'initialisation de $ndans sa première utilisation (3 octets supplémentaires enregistrés) et maintenant le code tient sur une seule ligne dans la zone de code ci-dessus.


@Trou noir. 85, en effet. J'ai probablement lu 86 (fait une sélection légèrement plus grande) et écrit 68 par erreur. Fixé maintenant.
axiac

1
Aucun problème :). Au fait, vous pouvez avoir 1 octet de moins: supprimez les parenthèses autour du echo, laissez juste un espace après.
Blackhole

1
Et puisque vous comptez bcscalerevenir true, vous pouvez utiliser $n=$argv[bcscale($argv[2])];et enregistrer 2 octets supplémentaires.
Blackhole

C'est un joli hack.
axiac

La saleté du code est un art: P. Oh, le dernier: bcpow($n,2)au lieu de bcmul($n,$n)vous enregistre 1 octet.
Blackhole

1

J, 27 octets

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

Explication:

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

Appelez ça comme ceci:

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

Une autre solution, légèrement plus cool:

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

Ce qui calcule les racines du polynôme x ^ 2 - nx - 1. Malheureusement, la façon dont J formate le résultat rend la récupération de la racine souhaitée légèrement plus longue.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.