Hochpräzise metallische Mittel

13

Hintergrund

Die metallischen Mittelwerte , beginnend mit dem berühmten goldenen Mittelwert , sind für jede natürliche Zahl (positive ganze Zahl) definiert und jede ist eine irrationale Konstante (sie hat eine unendliche, nicht wiederkehrende Dezimalerweiterung).

Für eine natürliche Zahl ist das metallische Mittel die Wurzel einer quadratischen Gleichung

Die Wurzeln sind immer

aber der metallische Mittelwert wird normalerweise als positive Wurzel angegeben. Für diese Frage wird also definiert durch:

Für das Ergebnis gilt der berühmte goldene Schnitt:


Herausforderung

Ihr Code sollte 2 Eingaben enthalten: n und p (die Reihenfolge ist nicht wichtig, solange sie konsistent ist)

  • n ist eine natürliche Zahl, die angibt, welches metallische Mittel
  • p ist eine natürliche Zahl, die angibt, wie viele Dezimalstellen genau sind

Ihr Code sollte den n-ten metallischen Mittelwert mit einer Genauigkeit von p Dezimalstellen ausgeben.

Gültigkeit

Ihr Code ist gültig, wenn er für Werte von n und p von 1 bis 65.535 funktioniert.

Sie müssen eine Dezimalstelle im Formular ausgeben

Ziffer (n). Ziffer (n) (ohne Leerzeichen)

Zum Beispiel ist der goldene Mittelwert bis 9 Dezimalstellen

1.618033988

Zeigen Sie die letzte Ziffer ohne Rundung an, da dies bei einer längeren Dezimalerweiterung der Fall wäre. Die nächste Ziffer im goldenen Mittel ist eine 7, die letzte 8 im Beispiel sollte jedoch nicht auf eine 9 aufgerundet werden.

Die Anzahl der Dezimalstellen muss p sein, was bedeutet, dass auch nachfolgende Nullen eingeschlossen werden müssen.

Antworten des Formulars

sind nicht gültig - Sie müssen eine Dezimalerweiterung verwenden.

Sie können bis zu 1 führende Zeile und bis zu 1 nachfolgende Zeile ausgeben. Sie dürfen außer den Ziffern und dem einzelnen Punkt / Punkt / Punkt keine Leerzeichen oder andere Zeichen ausgeben.

Ergebnis

Dies ist Standard Code Golf: Ihre Punktzahl ist die Anzahl der Bytes in Ihrem Code.


Bestenliste

(Mit Martins Leaderboard-Snippet )

Trichoplax
quelle

Antworten:

17

dc, 12

?kdd*4+v+2/p
  • ? Schieben Sie n und p auf den Stapel
  • k Stellen Sie die Präzision auf p
  • dd n zweimal duplizieren (insgesamt drei Exemplare)
  • * multiplizieren Sie n * n
  • 4+ addiere 4
  • v Quadratwurzel ziehen
  • + add n (letzte Kopie auf Stapel)
  • 2/ durch 2 teilen
  • p drucken

Testfall:

$ dc -f metalmean.dc <<< "1 9"
1.618033988
$
Digitales Trauma
quelle
7
Richtiges Werkzeug für den Job.
Dennis
5
@Dennis Es muss das erste Mal sein, dass CJam fast dreimal so lang ist wie etwas anderes ;-)
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))

Dadurch werden zwei Ganzzahlen aus STDIN gelesen und das Ergebnis an STDOUT ausgegeben. Sie können es online ausprobieren .

Ungolfed + Erklärung:

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

Wenn Sie die RmpfrBibliothek nicht installiert haben, können Sie install.packages("Rmpfr")und alle Ihre Träume werden wahr.

Alex A.
quelle
1

Mathematica, 50 Bytes

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

Definiert eine anonyme Funktion, die nund pin der richtigen Reihenfolge verwendet. Ich benutze Floor, um das Runden zu verhindern SetAccuracy, was ich brauche, um eine dezimale Ausgabe zu erhalten.

2012rcampion
quelle
@Arcinde Ich kann leider keine maschinengenauen Zahlen verwenden, da sie nicht in der Lage sind, damit umzugehen p>15.
2012rcampion
1

CJam, 35 Bytes

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

Liest zuerst p , dann n .

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

Wir berechnen einfach die Formel aus der Frage für n × 10 p , erhalten den ganzzahligen und den gebrochenen Teil des Ergebnisses geteilt durch 10 p , füllen den gebrochenen Teil mit führenden Nullen auf, um p- Ziffern zu erhalten, und drucken die durch einen Punkt getrennten Teile.

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
quelle
1

Python 2, 92 Bytes

Während ich mir jetzt die Antworten ansehe, sieht es so aus, als würde die CJam-Antwort dieselbe grundlegende Methode wie diese verwenden. Es berechnet die Antwort für n*10**pund fügt dann den Dezimalpunkt hinzu. Es ist unglaublich ineffizient, weil es den ganzzahligen Teil der Quadratwurzel berechnet (addiere einfach 1, bis es dort ankommt).

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
quelle
1

PHP, 85 78 Bytes

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

Es wird die mathematische Erweiterung BC Math verwendet , die auf einigen Systemen nicht verfügbar ist. Es muss in die Kompilierungszeit einbezogen werden, indem die --enable-bcmathBefehlszeilenoption angegeben wird. Es ist immer unter Windows verfügbar und scheint auch in der mit OSX gelieferten PHP-Version enthalten zu sein.

Update :

Ich habe alle von @blackhole in ihren Kommentaren vorgeschlagenen Hacks angewendet (danke!), Dann habe ich die Initialisierung für $ndie erste Verwendung zusammengedrückt (3 weitere Bytes gespeichert) und jetzt passt der Code in eine einzelne Zeile im obigen Code-Feld.

Axiac
quelle
@Schwarzes Loch. 85 in der Tat. Ich habe wahrscheinlich 86 gelesen (habe eine etwas größere Auswahl getroffen) und versehentlich 68 geschrieben. Jetzt behoben.
Axiac
1
Kein Problem :). Sie können übrigens 1 Byte weniger haben: Entfernen Sie die Klammer um das echo, lassen Sie einfach ein Leerzeichen dahinter.
Blackhole
1
Und da Sie eine bcscaleRückkehr erwarten true, können Sie $n=$argv[bcscale($argv[2])];2 weitere Bytes verwenden und sparen.
Blackhole
Das ist ein schöner Hack.
Axiac
Code Dreckigkeit ist eine Kunst: P. Oh, der letzte: bcpow($n,2)anstatt bcmul($n,$n)dir 1 Byte zu sparen.
Blackhole
1

J, 27 Bytes

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

Erläuterung:

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

Nenne es so:

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

Eine andere, etwas kühlere Lösung:

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

Was berechnet die Wurzeln des Polynoms x ^ 2 - nx - 1. Leider macht die Art und Weise, wie J das Ergebnis formatiert, das Zurückziehen der gewünschten Wurzel etwas länger.

Bolce Bussiere
quelle