Pi의 자릿수 계산


15

이것은 다소 다른 작업입니다. 1024 개의 16 진 자리에서 시작하여 π의 1024 개의 16 진수를 계산하십시오.

공식적으로 : 프로그램은 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

쉘 유틸리티 : 48

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

  • 모든 출력은 런타임에 "계산됩니다". (솔루션 게시를 통해 감사합니다)
  • 1 분 안에 실행됩니다. (인터넷 연결 속도에 따라 달라질 수 있음)

일반적으로 나는 그런 종류의 해결책을 공감합니다. 왜냐하면 규칙에 대한 일반적인 남용이고 더 이상 재미 없기 때문입니다. 그러나 제공된 참조 솔루션을 가져 와서 모든 출력을 쓰기에 너무 열악하여 런타임에 "출력"이 계산됩니다. (솔루션 게시 솔루션 덕분에) , 나는 당신에게
공감대를

골프 버전 : curl -sL ow.ly/shKGY|grep -Po \\w{99,}(37). 대시에서 작동합니다. 배시는 추가 바이트가 필요합니다.
데니스

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 공식 사용.

않습니다 NOT 1 분에서 실행 (: P 그러나 우리는 J의 답변을)

π의 처음 104 자리에 대한 예 (빠른 실행) :

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

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89
452821e638d01377be5466cf34e90c6cc0ac29b7

# :를 사용하여 숫자를 16 진수로 변환하지 않는 이유는 무엇입니까?
FUZxxl

무슨 말인지 잘 모르겠습니다. #:16 진수를 출력하지 않습니다.
Eelvex

IMHO는 현재 접근 방식보다 # :를 사용하여 16 진수를 생성하는 것이 더 쉽습니다.
FUZxxl

당신은 같은 것을 의미 (... 16 #:) Pi합니까? 숫자가 충분하지 않아서 생성해야한다고 생각합니다.
Eelvex

1
BTW, 나는 hfd숫자를 16 진수로 변환 하는 동사가 있음을 알았습니다 .
FUZxxl

5

자바 스크립트, 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))

Intel i5 코어를 사용하는 랩탑의 Chrome 14에서는 약 25 초가 걸립니다. 다른 사람이이 코드를 골프화 할 수 있습니까? 나는 골프를 잘 못해요 .. :(

아래는 골프가 아닙니다. 난 그냥 모든 의견을 제거하고 골프 루프로 변경했습니다.

에 대해 언급하지 마십시오 for(;s>=b;s-=b);s*=16;. 로 변경했습니다 s=(s%b)*16. :피

/**
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));

편집 : 완전히 사용하지 않는 기능을 제거했습니다. (왜 내가 그것을 유지 했습니까? : /)

추신. PI의 처음 100 자리

243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89452821e638d01377be5466cf34e90c6cc0ab


@FUZxxl : 골프가 아닌 코드가 충분하지 않습니까? .. :(
JiminP

사실이었다. 그러나 역동적 인 구문을 사용하는 대신 코드 형식을 사용하면 IMHO가 더 좋아 보입니다. 내가 쓴 것처럼, 당신이 싫어하면 자유롭게 되돌릴 수 있습니다.
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))
피터 테일러

일부는 상당히 커 보이지만 실제로는 모든 미세 최적화입니다. 가장 큰 절약은 운영자 _를 위해 중간에 두 개의 익명 함수를 제거함으로써 발생합니다 ,. 가장 까다로운 것은 하나의 함수를 병합 $하고 g하나의 함수로 만드는 것입니다. functionreturnSO를 모두 꽤 비싼 if(f)...else과 몇 ,1합리적인 트레이드 오프입니다.
피터 테일러

4

PHP 116114 바이트

<?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 개의 16 진수 숫자, 4 개의 16 진수 숫자를 계산하여 마지막 절반을 출력합니다. 실행 시간이 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 나누기를 점진적으로 계속하여 정밀도를 얻습니다.

파이썬 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 공식 사용 (물론).

1 분 안에 잘 작동합니다.


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

인텔 쿼드 코어에서 런타임 = 8.06 초


이것은 코드 골프입니다. 짧은 변수 이름을 사용하고 공백을 피하여 코드를 최대한 압축하십시오. 예를 들어, printf("%X",(int)gA)긴 목록 대신 사용하여 많은 문자를 저장할 수 있습니다.
FUZxxl 2016 년

1

PARI / GP-40 바이트

이 버전 \x은 결과의 16 진수를 표시하는 데 사용하여 '속임수'를 사용 합니다.

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

이 버전은 일반적인 방식으로 16 진수로 변환하는 데 87 바이트가 필요합니다.

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

두 버전 모두 1 초만에 실행됩니다.


1

펄-59

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

0.1 초 미만


0

쉘 68

도구 : bc -l, tr, 컷

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)에 있고 scale = 2466을 사용해야한다는 점을 반복적으로 조사했기 때문에 부정 행위로 간주 될 수 있습니다.

컷을 사용하는 아이디어를위한 breadbox에 감사합니다.


부정 행위로 간주 될 수있는 방법을 모르겠습니다. 숫자는 런타임에 계산됩니다. 실행할 때 마지막 숫자 (A 대신 7)에서 출력이 다릅니다. BTW, 나는 당신 이 몇 가지 문자를 저장하기 위해 dd명령을 바꿀 수 있다고 생각합니다 tail -c1024.
breadbox

예, 나는 그 차이도 관찰했습니다 (그리고 30 분을 보냈습니다 :)). bc에게 x 자릿수의 스케일을 사용하도록 지시하면 10 진수 모드에서 해당 자릿수로 반올림 한 다음 16 진수 변환을 수행합니다. 따라서 한 자리를 더 가져 가면 7이 아닌 69가 생성됩니다. 그러나 반올림 스타일 또는 잘림은 질문에 지정되지 않았습니다. 그리고 테일 아이디어에 감사드립니다. :)
알 수없는 사용자

질문은 다음을 지정합니다. 지정된 것과 동일하게 출력을 종료하고 생성합니다.
FUZxxl

@FUZxxl : "해야합니다 ...", "필수 ..."-16 진수 변환이 제대로 수행되는지 여부와 사양의 일부가 아니라 건너 뛸 문자 수를 확인하는 것이 도움이 될 것이라고 생각했습니다. , 1024의 마지막 숫자를 따르기 위해 16 자리 문자를주고 추가했습니다.
사용자가 알 수 없음

1
문장이 "공식적으로"라는 단어로 시작한다는 것을 감안할 때, 나는 OP가 아마도 단어 의 RFC 의미 에서 그것을 의미했음을 동의 할 것이다 . 또한, 당신은 아직도의 사용을 대체하여 새로운 솔루션을 향상시킬 수 dd와를 cut -c1027-2051. (쉘에는 텍스트 스트림을 조작하기위한 많은 도구가있다.)
breadbox
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.