Berechnen Sie die Ziffern von Pi

15

Dies ist eine etwas andere Aufgabe. Berechnen Sie 1024 hexadezimale Stellen von π, beginnend mit der 1024. hexadezimalen Stelle.

Formal: Ihr Programm sollte in weniger als 1 Minute fertig sein und die folgende Ausgabe erzeugen:

25d479d8f6e8def7e3fe501ab6794c3b976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a246368fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952ccc814544af5ebd09bee3d004de334afd660f2807192e4bb3c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320ad6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f83c7516dffd616b152f501ec8ad0552ab323db5fafd23876053317b483e00df829e5c57bbca6f8ca01a87562edf1769dbd542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e3362fb1341cee4c6e8ef20cada36774c01d07e9efe2bf11fb495dbda4dae909198eaad8e716b93d5a0d08ed1d0afc725e08e3c5b2f8e7594b78ff6e2fbf2122b648888b812900df01c4fad5ea0688fc31cd1cff191b3a8c1ad2f2f2218be0e1777ea752dfe8b021fa1e5a0cc0fb56f74e818acf3d6ce89e299b4a84fe0fd13e0b77cc43b81d2ada8d9165fa2668095770593cc7314211a1477e6ad206577b5fa86c75442f5fb9d35cfebcdaf0c7b3e8

Das Programm mit der kürzesten Länge gewinnt. Sie müssen alle Ziffern zur Laufzeit berechnen. Sie müssen den Algorithmus, der π berechnet, nicht implementieren. Wenn Ihre Sprache diese Funktionalität bereits bietet, können Sie sie verwenden.

FUZxxl
quelle
Hah, sollte einfach sein. (+1, immer noch) Ich wette, ich kann es in weniger als ein paar Sekunden ausführen lassen.
Mateen Ulhaq
@muntoo: Und? Wo ist deine Lösung?
FUZxxl
Ich habe vergessen, es zu tun. :) Übrigens, Geschwindigkeit! = Code-Golf.
Mateen Ulhaq
@muntoo: Ich weiß. Aber ich denke auch, dass 5 Tage eine gute Zeit für eine so einfache Aufgabe sind.
FUZxxl

Antworten:

13

Salbei, 29 char

Dies ist technisch gesehen kein Betrug, da die Ziffern zur Laufzeit berechnet werden. Das heißt, es ist immer noch billig wie die Hölle.

hex(floor(pi*2^8192))[1025:]
boothby
quelle
1
Auf keinen Fall betrügen.
FUZxxl
11
Mmmm, Boden pi.
Brotkasten
13

Shell-Dienstprogramme: 48

curl -sL ow.ly/5u3hc|grep -Eom 1 '[a-f0-9]{1024}'

  • Alle Ausgaben werden zur Laufzeit "berechnet". (Dank an OP, der die Lösung veröffentlicht)
  • Läuft in weniger als einer Minute. (hängt möglicherweise von der Geschwindigkeit Ihrer Internetverbindung ab)
user2074
quelle
Normalerweise habe ich solche Lösungen abgelehnt, weil sie ein verbreiteter Missbrauch der Regeln sind und nicht mehr lustig. Aber nur, weil Sie so schlau sind, die mitgelieferte Referenzlösung zu nehmen und zu schreiben. Alle Ausgaben werden zur Laufzeit "berechnet". (danke, dass OP die Lösung gepostet hat ) , ich gebe dir eine positive Bewertung;)
FUZxxl
Golfversion: curl -sL ow.ly/shKGY|grep -Po \\w{99,}(37). Funktioniert in Dash. Bash würde ein zusätzliches Byte benötigen.
Dennis
6

J, 156, 140, 137, 127

d=:3 :'1|+/4 _2 _1 _1*+/(y&(16^-)%1 4 5 6+8*])"0 i.y+9'
,1([:}.'0123456789abcdef'{~[:|.[:<.[:(],~16*1|{.)^:8 d)"0\1024x+8*i.128

Verwendung der BBP-Formel.

Läuft NICHT in weniger als einer Minute (aber wir haben eine J-Antwort: p)

Beispiel für die ersten 104 Stellen von π (das läuft schnell):

,1([:}.'0123456789abcdef'{~[:|.[:<.[:(],~16*1|{.)^:8 d)"0\8*i.13x

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89
452821e638d01377be5466cf34e90c6cc0ac29b7
Eelvex
quelle
Warum verwenden Sie nicht #:, um die Zahlen in Hexadezimalzahlen umzuwandeln?
FUZxxl
Ich bin mir nicht sicher was du meinst. #:gibt keine hexadezimalen Ziffern aus.
Eelvex
IMHO ist es einfacher, #: und eine Umformung zu verwenden, um hexadezimale Zahlen zu generieren, als Ihr aktueller Ansatz.
FUZxxl
Du meinst so etwas wie (... 16 #:) Pi? Ich denke, wir haben nicht genug Ziffern, also müssen wir sie trotzdem generieren.
Eelvex
1
Übrigens habe ich herausgefunden, dass es das Verb gibt hfd, um Zahlen in Hexadezimalzahlen umzuwandeln.
FUZxxl
5

JavaScript, 536

(Zeilenumbrüche und Einrückungen nur zur besseren Lesbarkeit)

var d='0123456789abcdef',p='',o='',l=3e3,c=0,e='length';d=d+d;
function $(n,r){return n[e]<=r?0:d.indexOf(n[r])}
function g(a,b){for(i=0,t='',s=16;i<l;i++,t+=d[~~(s/b)],s=(s%b)*16);
for(;a--;t=_(t,t,1));return t}
function _(a,b,s){for(i=(a[e]>b[e]?a[e]:b[e])-1,r='',c=0;i>=0;r=(s?
  function(k){c=k>15;return d[k]}($(a,i)+$(b,i)+c):
  function(k){c=k<0;return d[k+16]}($(a,i)-$(b,i)-c))+r,i--);return r}
for(i=0;i<l;i++,p+='2');
for(j=1;j<l;p=_(p,(o+='0')+_(_(_(g(2,8*j+1),g(1,8*j+4)),g(0,8*j+5)),g(0,8*j+6)),1),j++);
console.log(p.slice(1024,2048))

Auf meinem Laptop mit Intel i5 Core dauert es bei Google Chrome 14 ungefähr 25 Sekunden. Kann jemand anderen diesen Code Golf spielen? Ich kann nicht gut golfen .. :(

Unten ist nicht golfen. Ich entferne einfach alle Kommentare und wechsle für die Schleife zum Golfen.

Erwähne nichts über for(;s>=b;s-=b);s*=16;. Ich habe es in geändert s=(s%b)*16. : P

/**
Calculate PI-3 to 3000 (3e3) digits.
a : a
b : b
c : carry
d : digits
e : length
f : get from d
g : calculate (2^a)/b.
i,j, : for looping
l : length to calculate
p : pi
r,t : return value
*/
var d='0123456789abcdef',p='',o='',l=3e3,c=0,e='length';
d=d+d;//for carring

function $(n,r){return n[e]<=r?0:d.indexOf(n[r])}
/*
Calculate (2^a)/b. Assume that 2^a < b.
*/
function g(a,b){
    for(i=0,t='',s=16;i<l;i++){t+=d[~~(s/b)];for(;s>=b;s-=b);s*=16;}
    for(;a--;t=_(t,t,1));return t}
/*
Calculate a±b. (+ when s=1, - when s=0) When calculating minus, assume that 1>b>a>0.
*/
function _(a,b,s){
    for(i=(a[e]>b[e]?a[e]:b[e])-1,r='',c=0;i>=0;
        r=(s?function(k){c=k>15;return d[k]}($(a,i)+$(b,i)+c):
            function(k){c=k<0;return d[k+16]}($(a,i)-$(b,i)-c))+r,i--);return r;
}
/*
Using BBP formula. Calc when j=0...
4/1 - 2/4 - 1/5 - 1/6 = 3.22222222.... (b16)
*/
for(i=0;i<l;i++,p+='2');
//Calc when j>0
for(j=1;j<l;p=_(p,(o+='0')+_(_(_(g(2,8*j+1),g(1,8*j+4)),g(0,8*j+5)),g(0,8*j+6)),1),j++);
console.log(p.slice(1024,2048));

BEARBEITEN: Völlig unbenutzte Funktion entfernt. (Warum habe ich das behalten?: /)

PS. Erste 100 Stellen von PI

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ab

JiminP
quelle
@FUZxxl: War der Code ohne Golf nicht genug? .. :(
JiminP
Es war in der Tat. Aber meiner Meinung nach sieht es besser aus, wenn Sie die Code-Formatierung anstelle der Backtick-Syntax verwenden. Wie ich geschrieben habe, können Sie jederzeit zurückkehren, wenn Sie dies nicht mögen.
FUZxxl
d='0123456789abcdef',l=3e3,p=Array(l+1).join(2),o='',c=0,e='length';d+=d;function _(a,b,s){for(i=(a[e]>b[e]?a[e]:b[e])-1,r='',c=0;i+1;r=d[Z=F(b,i,1)+c,k=F(a,i,1)+(s?Z:16-Z),c=s?k>15:k<16,k]+r,i--);return r}function F(a,b,f){if(f)f=a[e]>b?d.indexOf(a[b]):0;else{for(i=0,f='',s=16;i++<l;f+=d[~~(s/b)],s=(s%b)*16);while(a--)f=_(f,f,1)}return f}for(j=0;++j<l;p=_(p,(o+='0')+_(_(_(F(2,z=8*j+1),F(1,z+3)),F(0,z+4)),F(0,z+5)),1));console.log(p.slice(1024,2048))
Peter Taylor
Das sind wirklich alle Mikrooptimierungen, obwohl einige von ihnen ziemlich groß aussehen. Die größte Ersparnis ergibt sich aus der Beseitigung der beiden anonymen Funktionen _zugunsten des ,Betreibers. Das schwierigste ist das Zusammenführen von $und gzu einer Funktion mit einem optionalen Argument zur Auswahl. functionund returnsind beide ziemlich teuer, so ist ein if(f)...elseund ein paar ,1ein vernünftiger Kompromiss.
Peter Taylor
4

PHP 116 114 Bytes

<?for(;$g?$d=0|($$g=$g--/2*$d+($$g?:2)%$g*$f)/$g--:4613^printf($i++>257?'%04x':'',$e+$d/$f=4*$g=16384)^$e=$d%$f;);

Diese Lösung berechnet alle pi bis zu 2048 Hexadezimalstellen, jeweils vier Hexadezimalstellen, und gibt die letzte Hälfte davon aus. Die Ausführungszeit beträgt weniger als 5 Sekunden. Die für die Berechnung verwendete Formel lautet wie folgt:

pi = 2 + 1/3*(2 + 2/5*(2 + 3/7*(2 + 4/9*(2 + 5/11*(2 + 6/13*(2 + 7/15*(2 + ... )))))))

Die Genauigkeit wird erhalten, indem die Reste in einem Array gespeichert und jede der 2 ^ 14 Unterteilungen inkrementell fortgesetzt werden.

Python 64 Bytes

x=p=16385
while~-p:x=p/2*x/p+2*2**8192;p-=2
print('%x'%x)[1025:]

Gleiche Methode wie oben. Läuft in ca. 0,2s.

Oder als Einzeiler in 73 Bytes :

print('%x'%reduce(lambda x,p:p/2*x/p+2*2**8192,range(16387,1,-2)))[1025:]
primo
quelle
3

PARI / GP-2.4, 141

forstep(d=1024,2047,8,y=frac(apply(x->sum(k=0,d+30,16^(d-k)/(8*k+x)),[1,4,5,6])*[4,-2,-1,-1]~);for(i=0,7,y=16*frac(y);printf("%X",floor(y))))

Natürlich mit der Bailey-Borwein-Plouffe-Formel.

Läuft in weniger als einer Minute.

Eelvex
quelle
3

C-Code:

long ki,k,e,d=1024;
int  dig,tD=0,c,Co=0,j,js[4]  ={1,4,5,6};
double res=0.0,tres=0.0,gT,ans[4] ={0.0};
while(tD < 1024)
{while(Co<4){ j= js[Co],gT=0.0,ki= 0;
 for(; ki < d+1;ki++){ k = 8*ki+j,e= d-ki,c=1; while(e--) c = 16*c % k; gT+=((double)(c)/(double)k);}
 ans[Co] = (gT - (int)gT),++Co;}
 double gA = 4*ans[0]-2*ans[1]-ans[2]-ans[3];
 gA = (gA<0) ? gA + -1*(int)gA +1 : gA -(int)gA;
 dig=0;while(dig++ < 6 && tD++ < 1024) gA *=16, printf("%X",gA),gA -= (int)gA;
 d+=6,Co = 0;}

Laufzeit = 8,06 Sekunden auf einem Intel Quad Core

johnnyR
quelle
Das ist Code Golf. Versuchen Sie, Ihren Code so weit wie möglich zu komprimieren, indem Sie kurze Variablennamen verwenden und Leerzeichen vermeiden. Zum Beispiel könnten Sie eine Menge Zeichen sparen, indem Sie printf("%X",(int)gA)anstelle dieser langen Liste verwenden.
FUZxxl
1

PARI / GP - 40 Bytes

Diese Version 'betrügt', indem sie verwendet wird \x, um die hexadezimalen Ziffern des Ergebnisses anzuzeigen.

\p8197
x=Pi<<4^6;x-=x\1;x=(x<<4^6)\1
\xx

Diese Version benötigt 87 Bytes, um auf die übliche Weise in Hexadezimal umzuwandeln.

\p8197
x=Pi<<4^6;x-=x\1;concat([Vec("0123456789abcdef")[n+1]|n<-digits((x<<4^6)\1,16)])

Beide Versionen laufen im Bruchteil einer Sekunde.

Charles
quelle
1

Perl - 59

use ntheory"Pi";say substr int(Pi(3000)<<8192)->as_hex,1027

Weniger als 0,1 s.

DanaJ
quelle
0

Schale 68

Werkzeuge: bc -l, tr, cut

echo "scale=2468;obase=16;4*a(1)"|bc -l|tr -d '\\\n'|cut -c1027-2051

Shell 64, tools: bc -l, tr, tail, unterscheidet sich in der Rundung der letzten Stelle

echo "scale=2466;obase=16;4*a(1)"|bc -l|tr -d '\\\n'|tail -c1024

Könnte als Betrug betrachtet werden, da das Wissen, wie man PI berechnet, in 4 * a (1) ist und dass 1 scale = 2466 verwendet werden muss, iterativ untersucht wurde.

Danke an breadbox für die Idee, cut zu verwenden.

Benutzer unbekannt
quelle
Ich verstehe nicht, wie das als Betrug angesehen werden könnte. Die Ziffern werden zur Laufzeit berechnet. Obwohl ich beachten sollte, dass sich die Ausgabe bei der letzten Ziffer (7 anstelle von A) unterscheidet, wenn ich sie ausführe. BTW, ich denke, Sie können den ddBefehl durch ersetzen tail -c1024, um ein paar Zeichen zu sparen.
Brotkasten
Ja, ich habe den Unterschied auch beobachtet (und eine halbe Stunde damit verbracht :)). Wenn ich bc anweise, eine Skala mit x Ziffern zu verwenden, wird im Dezimalmodus auf diese Ziffer gerundet und anschließend eine Hexadezimalumwandlung durchgeführt. Wenn ich also eine weitere Ziffer nehme, ergibt sich eine 69, keine 7. Allerdings wurde in der Frage weder ein Rundungsstil noch eine Kürzung angegeben. Und danke für die Schwanzidee. :)
Benutzer unbekannt
Die Frage lautet: Beenden und Erzeugen einer Ausgabe, die mit der angegebenen identisch ist.
FUZxxl,
@FUZxxl: "sollte ...", nicht "muss ..." - Ich dachte, es sollte hilfreich sein, zu überprüfen, ob die Hex-Konvertierung gut funktioniert, und die Anzahl der zu überspringenden Zeichen nicht als Teil der Spezifikation Aber ich gab nach und fügte 16 Zeichen hinzu, um eines zu ersetzen.
Benutzer unbekannt
1
Da der Satz mit dem Wort "Formal" beginnt, würde ich zustimmen, dass das OP es wahrscheinlich im RFC-Sinne des Wortes meinte . Auch können Sie Ihre neue Lösung verbessern , indem die Verwendung von Ersatz ddmit cut -c1027-2051. (Die Shell verfügt über zahlreiche Tools zum Bearbeiten von Textströmen.)
breadbox