Pi rakamlarını hesapla


15

Bu biraz farklı bir iş. 1024. onaltılık yerden başlayarak 1024 onaltılık π basamağını hesaplayın.

Resmi olarak: Programınız 1 dakikadan kısa sürede tamamlanmalı ve aşağıdaki çıktıyı üretmelidir:

25d479d8f6e8def7e3fe501ab6794c3b976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a246368fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952ccc814544af5ebd09bee3d004de334afd660f2807192e4bb3c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320ad6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f83c7516dffd616b152f501ec8ad0552ab323db5fafd23876053317b483e00df829e5c57bbca6f8ca01a87562edf1769dbd542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e3362fb1341cee4c6e8ef20cada36774c01d07e9efe2bf11fb495dbda4dae909198eaad8e716b93d5a0d08ed1d0afc725e08e3c5b2f8e7594b78ff6e2fbf2122b648888b812900df01c4fad5ea0688fc31cd1cff191b3a8c1ad2f2f2218be0e1777ea752dfe8b021fa1e5a0cc0fb56f74e818acf3d6ce89e299b4a84fe0fd13e0b77cc43b81d2ada8d9165fa2668095770593cc7314211a1477e6ad206577b5fa86c75442f5fb9d35cfebcdaf0c7b3e89a0d6411bd3ae1e7e4900250e2d2071b35e226800bb57b8e0af2464369bf009b91e5563911d59dfa6aa78c14389d95a537f207d5ba202e5b9c5832603766295cfa911c819684e734a41b3472dca7b14a94a

En kısa süreye sahip program kazanır. Çalışma zamanında tüm basamakları hesaplamanız gerekir. Π hesaplayan algoritmayı uygulamak zorunda değilsiniz; diliniz zaten bu işlevi sağlıyorsa kullanabilirsiniz.


Hah, kolay olmalı. (+1, yine de) Bahse girerim birkaç saniyeden daha kısa sürede çalıştırabilirim.
Mateen Ulhaq

@muntoo: Ya? Çözümünüz nerede?
FUZxxl

Yapmayı unuttum. :) BTW, hız! = Kod golf.
Mateen Ulhaq

@muntoo: Biliyorum. Ama bence, 5 gün böylesine kolay bir iş için iyi bir zaman.
FUZxxl

Yanıtlar:


13

Adaçayı, 29 karakter

Rakamlar çalışma zamanında hesaplandığından, bu teknik olarak hile yapmaz. Bununla birlikte, hala cehennem kadar ucuz.

hex(floor(pi*2^8192))[1025:]

1
Kesinlikle hile değil.
FUZxxl

11
Mmmm, taban pi.
breadbox

13

Shell Araçları: 48

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

  • Tüm çıktılar çalışma zamanında "hesaplanır". (OP'nin çözümü yayınlaması sayesinde)
  • Bir dakikadan kısa sürede koşar. (İnternet bağlantı hızınıza bağlı olabilir)

Genellikle bu tür çözümleri reddederim, çünkü kuralların ortak bir kötüye kullanımı ve artık komik değiller. Ancak sağlanan başvuru çözümünü almak ve yazmak için çok sinsi olduğunuz için Tüm çıktılar çalışma zamanında "hesaplanır". (OP'nin çözümü paylaşması sayesinde) , size bir oy verin;)
FUZxxl

Golfçü versiyon: curl -sL ow.ly/shKGY|grep -Po \\w{99,}(37). Dash'de çalışıyor. Bash için ek bir bayt gerekir.
Dennis

6

J, 156, 140, 137127

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

BBP formülü kullanma.

Does DEĞİL Bir dakika içinde çalıştırın (: p ama biz J cevabım var)

İlk 104 basamaklı π örneği (bu hızlı çalışır):

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

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89
452821e638d01377be5466cf34e90c6cc0ac29b7

Neden sayıları onaltılık biçime dönüştürmek için #: kullanmıyorsunuz?
FUZxxl

Neyi kastettiğinden emin değilim. #:onaltılık basamak basmaz.
Eelvex

IMHO #: kullanmak ve onaltılık basamaklar oluşturmak için yeniden şekillendirmek mevcut yaklaşımınızdan daha kolaydır.
FUZxxl

Gibi bir şey (... 16 #:) Pimi demek istiyorsun ? Sanırım yeterince rakamımız yok, bu yüzden onları yine de üretmeliyiz.
Eelvex

1
BTW, hfdsayıları onaltılık biçime dönüştürecek fiil olduğunu öğrendim .
FUZxxl

5

JavaScript, 536

(Çizgi okunmaları ve yalnızca okunabilirlik için girinti)

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

Intel i5 çekirdeğini kullanarak dizüstü bilgisayarımdaki Google Chrome 14'te yaklaşık 25 saniye sürer. Başka biri bu kodu golf oynayabilir mi? İyi golf yapamam .. :(

Aşağıda golf yok. Ben sadece tüm yorumları kaldırmak ve golf döngü için değişti.

Bahsetme for(;s>=b;s-=b);s*=16;. Ben olarak değiştirdim 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));

EDIT: Tamamen kullanılmayan fonksiyon kaldırıldı. (Bunu neden sakladım?: /)

PS. PI'nin ilk 100 basamağı

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ab


@FUZxxl: Golf dışı kod yeterli değil mi? .. :(
JiminP

Gerçekten de öyleydi. Ancak IMHO, backtick sözdizimini kullanmak yerine kod biçimlendirmesini kullanırsanız daha iyi görünür. Yazdığım gibi, sevmediğiniz takdirde geri dönmekten çekinmeyin.
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

Bazıları oldukça büyük görünse de, bu gerçekten tüm mikro optimizasyonlar. En büyük tasarruf, ortadaki iki anonim fonksiyonu operatörün _lehine ortadan kaldırmaktır ,. En zor olanı, aralarında seçim yapmak için isteğe bağlı bir argüman ile bir işlevin birleştirilmesi $ve gbir işlevin birleştirilmesidir . functionve returnher ikisi de oldukça pahalı, bu yüzden bir if(f)...elseve bir çift ,1makul bir takas.
Peter Taylor

4

PHP 116 114 bayt

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

Bu çözüm, 2048'e kadar onaltılık hane, bir seferde dört onaltılık hane kadar pi hesaplar ve bunların son yarısını çıkarır. Yürütme süresi 5 saniyeden az. Hesaplama için kullanılan formül aşağıdaki gibidir:

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

Kesinlik, geri kalanları bir dizide saklayarak ve 2 ^ 14 bölümünün her birini aşamalı olarak sürdürerek elde edilir.

Python 64 bayt

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

Yukarıdaki ile aynı yöntem. Yaklaşık 0.2 saniye içinde çalışır.

Veya 73 baytta tek astar olarak :

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

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

Bailey – Borwein – Plouffe formülünü kullanarak (elbette).

Bir dakikadan kısa sürede iyi çalışır.


3

C kodu:

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;}

intel Quad core'da çalışma zamanı = 8.06 saniye


Bu kod golf. Kısa değişken adları kullanarak ve boşluktan kaçınarak kodunuzu mümkün olduğunca sıkıştırmaya çalışın. Örneğin printf("%X",(int)gA), bu uzun liste yerine kullanarak birçok karakter kaydedebilirsiniz .
FUZxxl

1

PARI / GP - 40 bayt

Bu sürüm \xsonucun onaltılık rakamlarını görüntülemek için 'hile yapar' .

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

Bu sürüm, normal şekilde onaltılık biçime dönüştürmek için 87 bayt alır.

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

Her iki versiyon da saniyenin küçük bir bölümünde çalışır.


1

Perl - 59

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

0.1 saniyeden az.


0

Kabuk 68

araçlar: bc -l, tr, kes

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

Shell 64, araçlar: bc -l, tr, kuyruk, son yerin yuvarlanmasında farklılık gösterir

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

PI'nin nasıl hesaplanacağı bilgisi 4 * a (1) olduğu ve 1'in ölçek = 2466 kullanması gerektiği bilgisi yinelemeli olarak araştırıldığı için hile olarak düşünülebilir.

Kesim kullanımı fikri için breadbox'a teşekkürler.


Hile olarak nasıl değerlendirilebileceğini anlamıyorum; basamaklar çalışma zamanında hesaplanır. Her ne kadar ben çalıştırdığımda, çıkış son basamak (A yerine 7) farklı olduğunu unutmayın. BTW, birkaç karakter kaydetmek için ddkomutu yerine koyabileceğinizi düşünüyorum tail -c1024.
breadbox

Evet, farkı da gözlemledim (ve yarım saat harcadım :)). BC'ye x basamaklı bir ölçek kullanmasını söylersem, ondalık modda bu rakama yuvarlar ve daha sonra onaltılık dönüştürme yapar. Yani bir basamak daha alırsam, 7 değil 69 üretir. Ancak - soruda yuvarlama stili veya kesme belirtilmedi. Ve kuyruk fikri için teşekkürler. :)
kullanıcı bilinmiyor

Soru şunu belirtir: belirtilenle aynı çıktıyı sonlandırır ve üretir.
FUZxxl

@FUZxxl: "gerekir ..." değil, "olmalı ..." - Ben onaltılık dönüşüm iyi olup olmadığını kontrol etmek için bir yardımcı olacağını düşündüm, ve karakter sayısı atlamak, belirtimin bir parçası olarak değil 1024'ün son basamağına uymak için. Ama bir tane yerine 16 karakter verdim ve ekledim.
kullanıcı bilinmiyor

1
Cümlenin "Formally" kelimesiyle başladığı göz önüne alındığında, OP'nin muhtemelen kelimenin RFC anlamında kastettiğini kabul ediyorum . Ayrıca, yine kullanımını değiştirerek yeni bir çözüm geliştirebilir ddile cut -c1027-2051. (Kabukta metin akışlarını işlemek için birçok araç vardır.)
breadbox
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.