คำนวณตัวเลขของ Pi


15

นี่เป็นงานที่ค่อนข้างแตกต่าง คำนวณ 1024 ฐานสิบหกหลักของπเริ่มต้นที่ตำแหน่งเลขฐานสิบหกที่ 1024

เป็นทางการ: โปรแกรมของคุณควรเสร็จสมบูรณ์ในเวลาน้อยกว่า 1 นาทีและสร้างผลลัพธ์ต่อไปนี้:

25d479d8f6e8def7e3fe501ab6794c3b976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a246368fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952ccc814544af5ebd09bee3d004de334afd660f2807192e4bb3c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320ad6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f83c7516dffd616b152f501ec8ad0552ab323db5fafd23876053317b483e00df829e5c57bbca6f8ca01a87562edf1769dbd542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e3362fb1341cee4c6e8ef20cada36774c01d07e9efe2bf11fb495dbda4dae909198eaad8e716b93d5a0d08ed1d0afc725e08e3c5b2f8e7594b78ff6e2fbf2122b648888b812900df01c4fad5ea0688fc31cd1cff191b3a8c1ad2f2f2218be0e1777ea752dfe8b021fa1e5a0cc0fb56f74e818acf3d6ce89e299b4a84fe0fd13e0b77cc43b81d2ada8d9165fa2668095770593cc7314211a1477e6ad206577b5fa86c75442f5fb9d35cfebcdaf0c7b3e89a0d6411bd3ae1e7e4900250e2d2071b35e226800bb57b8e0af2464369bf009b91e5563911d59dfa6aa78c14389d95a537f207d5ba202e5b9c5832603766295cfa911c819684e734a41b3472dca7b14a94a

โปรแกรมที่มีความยาวสั้นที่สุดจะเป็นผู้ชนะ คุณต้องคำนวณตัวเลขทั้งหมดที่รันไทม์ คุณไม่จำเป็นต้องใช้อัลกอริทึมที่คำนวณπ; หากภาษาของคุณมีฟังก์ชั่นการใช้งานนั้นอยู่แล้วคุณสามารถใช้งานได้


ฮ่าฮ่าน่าจะง่ายนะ (+1 ยัง) ฉันเดิมพันฉันสามารถทำให้มันทำงานในเวลาไม่กี่วินาที
Mateen Ulhaq

@muntoo: และ? ทางออกของคุณอยู่ที่ไหน
FUZxxl

ฉันลืมที่จะทำ :) BTW ความเร็ว! = รหัสกอล์ฟ
Mateen Ulhaq

@muntoo: ฉันรู้ แต่ฉันก็คิดว่า 5 วันนั้นเป็นช่วงเวลาที่ดีสำหรับงานง่าย ๆ
FUZxxl

คำตอบ:


13

ปราชญ์ 29 อักขระ

นี่ไม่ใช่การโกงทางเทคนิคเนื่องจากมีการคำนวณตัวเลขที่รันไทม์ ที่กล่าวว่ายังคงราคาถูกเหมือนนรก

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

1
ไม่โกงแน่นอน
FUZxxl

11
อืมมม. พื้นปี่
breadbox

13

Shell Utilities: 48

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

  • เอาท์พุททั้งหมดคือ "คำนวณ" ที่รันไทม์ (ขอบคุณ OP การโพสต์วิธีแก้ปัญหา)
  • ทำงานในไม่กี่นาที (อาจขึ้นอยู่กับความเร็วการเชื่อมต่ออินเทอร์เน็ตของคุณ)

ปกติแล้วฉันจะลงคะแนนแก้ปัญหาแบบนั้นเพราะมันเป็นการละเมิดกฎทั่วไปและไม่ตลกอีกต่อไป แต่เพียงเพราะคุณส่อเสียดมากที่จะใช้โซลูชันอ้างอิงที่ให้มาและเขียนเอาต์พุตทั้งหมดคือ "คำนวณ" ที่รันไทม์ (ขอบคุณ OP การโพสต์วิธีแก้ปัญหา)ฉันให้ upvote;)
FUZxxl

รุ่น Golfed: curl -sL ow.ly/shKGY|grep -Po \\w{99,}(37) ทำงานใน Dash Bash จะต้องมีไบต์เพิ่ม
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

ใช้สูตร BBP

ไม่ไม่ทำงานในภายใต้นาที ( แต่เรามีคำตอบที่ J: p)

ตัวอย่างสำหรับ 104 หลักแรกของπ (การดำเนินการนี้เร็ว)

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

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89
452821e638d01377be5466cf34e90c6cc0ac29b7

ทำไมคุณไม่ใช้ #: เพื่อแปลงตัวเลขให้เป็นเลขฐานสิบหก
FUZxxl

ฉันไม่แน่ใจว่าคุณหมายถึงอะไร #:จะไม่ส่งออกเลขฐานสิบหก
Eelvex

IMHO ง่ายกว่าการใช้ #: และ reshape เพื่อสร้างเลขฐานสิบหกกว่าวิธีการปัจจุบันของคุณ
FUZxxl

คุณหมายถึงสิ่งที่ต้องการ(... 16 #:) Pi? ฉันคิดว่าเรามีตัวเลขไม่เพียงพอเราจึงต้องสร้างมันต่อไป
Eelvex

1
BTW ฉันพบว่ามีคำกริยาhfdในการแปลงตัวเลขเป็นเลขฐานสิบหก
FUZxxl

5

JavaScript, 536

(การแพร่กระจายและการเยื้องสำหรับความชัดเจนเท่านั้น)

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

ใช้เวลาประมาณ 25 วินาทีบน Google Chrome 14 บนตักของฉันโดยใช้ Intel i5 core คนอื่นสามารถตีรหัสนี้ได้หรือไม่ ฉันเล่นกอล์ฟไม่เก่ง .. :(

ด้านล่างนี้ไม่ใช่สนามกอล์ฟ ฉันเพิ่งลบความคิดเห็นทั้งหมดและเปลี่ยนเป็นวงสำหรับเล่นกอล์ฟ

for(;s>=b;s-=b);s*=16;ไม่ต้องพูดถึงเกี่ยวกับ 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));

แก้ไข: ลบฟังก์ชั่นที่ไม่ได้ใช้ออกทั้งหมด (ทำไมฉันถึงเก็บไว้?: /)

PS 100 หลักแรกของ PI

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ab


@FUZxxl: รหัสที่ไม่ใช่กอล์ฟไม่เพียงพอหรือไม่ .. :(
JiminP

มันเป็นจริง แต่ IMHO มันดูดีกว่าถ้าคุณใช้การจัดรูปแบบรหัสแทนการใช้ไวยากรณ์ backtick ตามที่ฉันเขียนรู้สึกฟรีเพื่อยกเลิกถ้าคุณไม่ชอบ
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

นั่นคือการปรับขนาดเล็กทั้งหมดแม้ว่าบางส่วนจะดูค่อนข้างใหญ่ การประหยัดที่ใหญ่ที่สุดมาจากการกำจัดทั้งสองฟังก์ชั่นนิรนาม_ในความโปรดปรานของ,ผู้ประกอบการ สิ่งที่ยากที่สุดก็คือการรวมกันของ$และgเป็นหนึ่งในฟังก์ชั่นที่มีอาร์กิวเมนต์ตัวเลือกเพื่อเลือกระหว่างพวกเขา functionและreturnทั้งคู่มีราคาค่อนข้างแพงดังนั้นข้อเสียif(f)...elseสองสามข้อ,1จึงสมเหตุสมผล
Peter Taylor

4

PHP 116 114 ไบต์

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

โซลูชันนี้คำนวณไพทั้งหมดได้ถึง 2048 หลักหกหลักเลขฐานสิบหกในแต่ละครั้งและส่งออกครึ่งสุดท้ายของพวกเขา เวลาดำเนินการน้อยกว่า 5 วินาที สูตรที่ใช้สำหรับการคำนวณมีดังต่อไปนี้:

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

ความแม่นยำได้รับการจัดเก็บส่วนที่เหลือในอาร์เรย์และดำเนินการต่อในแต่ละหน่วย 2 ^ 14 เพิ่มขึ้น

Python 64 ไบต์

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

วิธีการเช่นเดียวกับข้างต้น ทำงานในประมาณ 0.2 วินาที

หรือเป็นแบบหนึ่งซับใน 73 ไบต์ :

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 (แน่นอน)

ทำงานได้ดีในไม่กี่นาที


3

รหัส C:

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

runtime = 8.06 วินาทีบน intel Quad core


นี่คือรหัสกอล์ฟ พยายามบีบอัดรหัสของคุณให้มากที่สุดโดยใช้ชื่อตัวแปรแบบสั้นและหลีกเลี่ยงช่องว่าง ตัวอย่างเช่นคุณสามารถบันทึกตัวอักษรจำนวนมากได้โดยใช้printf("%X",(int)gA)แทนรายการแบบยาว
FUZxxl

1

PARI / GP - 40 ไบต์

รุ่นนี้ 'กลโกง' โดยใช้\xเพื่อแสดงตัวเลขฐานสิบหกของผลลัพธ์

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

รุ่นนี้ใช้เวลา 87 ไบต์ในการแปลงเป็นเลขฐานสิบหกในวิธีปกติ

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

ทั้งสองรุ่นทำงานในเสี้ยววินาที



0

เชลล์ 68

เครื่องมือ: bc -l, tr, cut

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

เชลล์ 64, เครื่องมือ: bc -l, tr, tail, แตกต่างกันในการปัดเศษของตำแหน่งสุดท้าย

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

อาจถือว่าเป็นการโกงเนื่องจากความรู้วิธีการคำนวณ PI อยู่ใน 4 * a (1) และ 1 นั้นต้องใช้ scale = 2466 ได้รับการตรวจสอบซ้ำแล้วซ้ำอีก

ขอบคุณ breadbox สำหรับแนวคิดที่จะใช้การตัด


ฉันไม่เห็นว่ามันจะเป็นการโกงอย่างไร ตัวเลขถูกคำนวณ ณ รันไทม์ แม้ว่าฉันควรทราบว่าเมื่อฉันเรียกใช้มันเอาท์พุทที่แตกต่างกันในหลักสุดท้าย (7 แทน A) BTW ฉันคิดว่าคุณสามารถแทนที่ddคำสั่งด้วยtail -c1024เพื่อบันทึกไม่กี่ตัวอักษร
breadbox

ใช่ฉันสังเกตเห็นความแตกต่างด้วย (และใช้เวลาครึ่งชั่วโมงกับมัน :)) ถ้าฉันบอก bc ให้ใช้สเกลดิจิตัล x ​​มันจะปัดเศษเป็นตัวเลขนั้นในโหมดเลขฐานสิบและทำการแปลงเลขฐานสิบหกหลังจากนั้น ดังนั้นถ้าฉันใช้อีกหนึ่งหลักมันจะสร้าง 69 ไม่ใช่ 7 อย่างไรก็ตาม - ไม่ได้ระบุรูปแบบการปัดเศษหรือการปัดเศษในคำถาม และขอบคุณสำหรับความคิดหาง :)
ผู้ใช้ไม่รู้จัก

คำถามที่ระบุ: ยุติและสร้างผลลัพธ์ที่เหมือนกันกับสิ่งที่ระบุ
FUZxxl

@FZZxxl: "ควร ... " ไม่ใช่ "ต้อง ... " - ฉันคิดว่าควรช่วยตรวจสอบว่าการแปลงเลขฐานสิบหกทำได้ดีหรือไม่และจำนวนตัวอักษรที่จะข้ามไม่ใช่ส่วนหนึ่งของข้อกำหนด เพื่อให้สอดคล้องกับหลักสุดท้ายของ 1024 แต่ฉันให้และเพิ่ม 16 ตัวอักษรแทนหนึ่งตัว
ผู้ใช้ที่ไม่รู้จัก

1
เนื่องจากประโยคเริ่มต้นด้วยคำว่า "อย่างเป็นทางการ" ฉันจะยอมรับว่า OP อาจหมายถึงมันในความหมายของคำRFC นอกจากนี้คุณยังสามารถปรับปรุงวิธีการแก้ปัญหาของคุณใหม่ด้วยการเปลี่ยนการใช้ด้วยdd cut -c1027-2051(เชลล์มีเครื่องมือมากมายสำหรับจัดการสตรีมข้อความ)
breadbox
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.