바보 같은 제한과 사막


18

그래서, 당신은 책상에 앉아 pi의 처음 20 자리를 계산하는 프로그램을 골프로 쳤으며, 상사가 와서 사과 IIe를 창 밖으로 내 보냅니다. 이제 새 프로젝트를 진행 중이며이 컴퓨터에는 아직 텍스트 기능이 없습니다. 없음 글꼴이 없습니다. 아무것도.

이제 그 프로그램을 마치겠습니다. 프로그램의 일부가 아닌 글꼴을 사용하지 않고 pi의 처음 20자를 계산 하고 표시 하십시오. 출력은 이미지 파일 (jpeg, png, gif, svg (문자를 사용하지 않는 한), bmp, xpm)로 표준 출력으로 표시하거나 쓸 수 있습니다. 모든 언어를 사용할 수 있지만 언어의 글꼴 기능, 텍스트 표시 등을 사용할 수는 없습니다.

작은 보너스 (10 자) Lisa에서 작동하는 경우.

편집 : 그것을 이해하지 못한 사람들을 위해 나의 영감은 첫 번째 맥이었고 제목은 말장난입니다. 애니메이션 GIF가 정말 멋진 @Sukminder에게 큰 찬사를 보냅니다. 더 나은 답변이 나오면 대회는 끝나지 않습니다.


나는 도전을 좋아하지만 기술적으로도 그러한 시스템도 소스 코드를 표시 할 수 없습니까? 물론 Piet를 제외하고.
ApproachingDarknessFish

2
@ValekHalfHeart 다른 기계에서 소스 코드를로드 할 수 있습니다
John Dvorak

1
그리고 사람이 읽을 수있는 것을 어떻게 정의합니까? 예를 들어, 필자는 필기를 일부 사람 (적어도 한 사람)이 읽을 수 있지만 다른 사람은 읽을 수 없습니다. (그런데 2 ^ (2x2) = 16, 11 자리 모두에 대한 글리프가 충분합니다.;))
Kendall Frey

4
나는 제목을 전혀 이해하지 못하고, 텍스트 디스플레이를 사용할 수 없을 때 ASCII 아트를 어떻게 사용할 수 있는지 이해하지 못하며, 질문은 "PI 계산"의 정의가 매우 필요합니다.
피터 테일러

2
"pi 계산"은 실제로 무엇을 의미합니까? 처음 20 진수의 비트 맵을 하드 코딩 할 수 있습니까? (내장 된 PI 상수 또는 이와 유사한 것을 사용하지 않음)
FireFly

답변:


6

파이썬, 222 자

n=[10**20*277991633/1963319607/10**i%10 for i in range(19,1,-1)]
print' *     *'
print' * **    '+' '.join(' ** * ***** *****  *'[2*d:2*d+2]for d in n)
print'**     * '+' '.join('**  *    * ** ***** '[2*d:2*d+2]for d in n)

첫 번째 줄은 근사법을 사용하여 pi의 자리수를 계산합니다 pi-3 ~= 277991633/1963319607. 다음 3 줄은 ASCII art Nemeth Braille을 사용하여 20 자의 pi를 출력 합니다.

 *     *
 * **    *  ** *  *   * *  ** *  ** *  *   * **  * ** *  ** * 
**     *     *     * *  *  *   *     * ** *  ** *     *     **

저는 여기서 "계산 Pi"와 "사람이 읽을 수있는"감각에서 두 방향으로 경계를 넓 힙니다.


3
이런 젠장? 텍스트 출력을 사용해서는 안된다고 생각했습니다. 컴퓨터 *에서 글꼴없이 및 공백 을 어떻게 렌더링 합니까?
boothby

@boothby : ASCII 아트입니다. *1x1 검정색 픽셀과`를 1x1 흰색 픽셀로 생각하십시오 .
키이스 랜달

1
그는 요점을 얻었다. *글꼴을 사용하지 않고 렌더링 할 수는 없습니다. 실격이라고 생각합니다.
Sirens

18

파이썬, 217 바이트

파이썬 이미징 라이브러리가 필요합니다

import Image
x=p=141
i=Image.new('1',(x,11))
while~-p:x=p/2*x/p+2*10**19;p-=2
for c in str(x):[i.putpixel((j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2),1&ord('}`7gjO_a\177o'[int(c)])>>j%7)for j in range(17)];p+=7
i.show()

바이트 수는 이스케이프 된 문자 \177가 리터럴로 대체 된 것으로 가정합니다 (char 127 ).

출력은 다음과 같이 나타납니다 (기본 * .bmp 뷰어에서 열립니다).

원하는 수의 자릿수를 인쇄하도록 쉽게 매개 변수화 할 수 있습니다. 다음은 stdin에서 정수 입력을 허용하고 많은 자릿수를 표시합니다.

import Image
n=input()
x=p=n*7|1
i=Image.new('1',(x,11))
while~-p:x=p/2*x/p+2*10**(n-1);p-=2
for c in str(x):[i.putpixel((j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2),1&ord('}`7gjO_a\177o'[int(c)])>>j%7)for j in range(17)];p+=7
i.show()

n = 80에 대한 출력 :


파이 계산

while~-p:x=p/2*x/p+2*10**19;p-=2

그렇습니다. 사용 된 공식은 오일러 변환 (Euler 's Transform)라이프니츠 (Leibniz) 시리즈 에 적용한 후 나머지 합계에서 각 항을 인수 분해 한 결과입니다 . 공식은 선형 적으로 수렴합니다. 각 숫자에는 로그 2 (10) ≈ 3.32 반복이 필요합니다. 파생에 관심이있는 사람은 부록 A를 참조하십시오.

디스플레이

PIL 은 내가 아는 가장 편리한 라이브러리이기 때문에 이미지 생성에 사용됩니다. 빈 141 × 11 흑백 비트 맵이 생성 된 다음 한 번에 한 픽셀 씩 7 세그먼트 방식으로 흰색 선이 그려집니다. 각 세그먼트를 그리는 데 필요한 위치는 비트 마스크 문자열에 저장되며 비트는 다음 위치에 해당합니다.

 000
3   5
3   5
 111
4   6
4   6
 222

마법의 비트는 (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)다음 순서 (base-18)로 각 픽셀을 생성합니다.

(2, 2), (2, 5), (2, 8), (1, 3), (1, 6), (5, 3), (5, 6),
(3, 2), (3, 5), (3, 8), (1, 4), (1, 7), (5, 4), (5, 7),
(4, 2), (4, 5), (4, 8)

 07e
3   5
a   c
 18f
4   6
b   d
 29g

부록

오일러 변환은 절대 단조 수렴을 표시하는 모든 시리즈에서 작동하는 수렴 가속 기술입니다. 결과 계열은 일반적으로 용어 당 1 비트의 속도로 선형으로 수렴합니다 (원래 계열이 이미 초선 형인 경우 결과 계열은 실제로 더 느리게 수렴 됨). 순수하게 수학적 설명 I는 절차 적 접근 방식을 맡게 될 거 야, 그래서 따라하기 조금 어렵다.

우리는 라이프니츠 시리즈부터 시작할 것입니다 :

그런 다음 이웃 용어를 결합하여 각 용어를 반으로 나눕니다.

쉽게 한:

일반화 :

선행 ½에는 파트너 용어가 없으므로 나머지 합계에서 제외되었습니다. 이것은 변형 된 시리즈의 첫 번째 용어입니다. 다음 용어를 찾기 위해 프로세스를 다시 반복하십시오.

그리고 다시:

그리고 다시:

그리고 좋은 측정을 위해 한 번 더 :

이 시점에서 우리는 처음 5 개의 용어를 가지고 있으며, 6 번째 용어는 분명합니다. 일반화하기에 충분하므로 여기서 멈출 것입니다. 분자와 분모를 분해하여 시작하겠습니다.

분모에는 2n + 1이중 계승 이 포함되어 있으므로 다음과 같이 패치합니다.

분모에서 2 를 설명하지 않는 처음 두 항을 제외하고 모든 것이 적합 합니다. 전체 표현식에 2를 곱하면 문제를 해결할 수 있습니다 .

2 3 = 2 · 4 이므로

분자는 이제 n 으로 쉽게 식별 될 수 있습니다 ! .

각 연속 항에 추가되는 요인 n / (2n + 1)n 이 커짐에 따라 1/2에 가까워 지므로 항당 1 비트의 속도로 선형 수렴을 의미합니다. 이것은 실제로 의도적으로 설계된 것입니다. 좋은 결과이지만 거기에 계승이 없으면 더 좋을 것입니다. 여기서 우리가 할 수있는 것은 각 연속 된 항을 나머지 합계에서 제외하여 중첩 된 표현식을 생성하는 것입니다.



이것은 되풀이 관계로 다시 작성할 수 있습니다.

여기서 n 은 ⌈ log 2 (10) · d ⌉ .. 0 부터 거꾸로 계산 됩니다. 여기서 d 는 필요한 자릿수입니다.

이 반복의 안정적인 점이 정확히 2 ( 위의 구현에서와 같이 두 배가 된 경우 4 )이므로 올바르게 초기화하여 여러 반복을 저장할 수 있습니다. 그러나 임의의 값으로 초기화하면 다른 곳에서 필요하고 상단에 몇 가지 추가 반복을 던지는 것이 일반적으로 바이트 단위로 저렴합니다.


1
수업에 감사드립니다! 내가 얻지 못하는 것은 pin 이하 p/2 * x/p + ...는 일입니다. AIUI Python은 더 큰 데이터 형식으로 자동 승격을 지원하므로 정밀해서는 안되지만 어쨌든 그 p문제는 중요합니다. 그들에게 ... 내가 여기서 무엇을 놓치고 있습니까?
FireFly

@FireFly가 p홀수로 초기화되었으므로 p/2/p정수 나누기에서-와 같습니다 ((p-1)/2)/p. 이것은이 생성 1/3, 2/5, 3/7등의 용어는 상기 유도.
primo

12

#C – 777 자

C – 731 자

GIF를에 인쇄합니다 stdout.

  • Quirk : 처음에는 쉼표가 없습니다 3.

미리 구성된 헤더 + 5x5 픽셀의 홈 브루 (임베디드) 글꼴로 표시되는 각 숫자에서 GIF 연결

결과

여기에 이미지 설명을 입력하십시오

있습니다 --- ^

한 번 실행 한 후 Chrome에서 GIF가 사라지는 경우가 있습니다.

#include <stdio.h>
#define G 68,30
#define F(e,i)for(i=0;i<e;++i)
#define B w[++k]
unsigned char r[][10]={{4,18,150,199,188,159,10,0},{4,18,102,169,188,122,64,1},{G,160,166,104,217,80,1},{G,160,166,184,140,66,1},{68,96,153,193,135,138,66,1},{G,6,107,199,155,80,40},{68,128,150,22,173,218,90,1},{G,160,182,169,254,84,1},{G,6,138,153,140,10,0},{G,6,138,185,250,66,1},{0,0,0,5,0,5,0,0,2,8}},w[440]={71,73,70,56,57,97,100,0,5,0,144,0,0,255,255,255,0,0,0};int main(){int a=10000,b=0,c=70,d,e=0,f[71],g;int i,j,k=18,s=0;char m[5];for(;b<c;)f[b++]=a/5;for(;d=0,g=c*2;c-=14,e=d%a){for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);sprintf(m,"%d",e+d/a);F(4,i){B=44;B=s++*5;F(10,j)B=r[10][j];F(8,j)B=r[m[i]-'0'][j];B=0;}}B=59;fwrite(w,1,k,stdout);}

짧은 소개 :

PI 계산

Pi는 약간 수정 된 Dik Winter 버전과 Achim Flammenkamp의 Rabinowitz 구현 및 Wagon 알고리즘을 사용하여 π의 숫자를 계산합니다.

int a=10000,b,c=2800,d,e,f[2801],g;main(){for(;b-c;)f[b++]=a/5;for(;d=0,g=c*2;c
-=14,printf("%.4d",e+d/a),e=d%a)for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);}

GIF 생성

GIF 이미지에는 canvas헤더에 속성이 있습니다. left각 자릿수에 따라 속성을 설정하여 여러 이미지를 표시하는 것과 함께 사용할 수 있습니다. 여기서 각 자릿수는 내장 된 이미지입니다.

선적 서류 비치.

예:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

3 : left  0 pixels
1 : left  5 pixels
4 : left 10 pixels
… and so on.

확장 된 코드 (많은 주석 포함)

지저분하지만 그것은 최소화의 일부입니다 .

#include <stdio.h>
#define G 68,30
#define F(e,i)for(i=0;i<e;++i)
#define B w[++k]

/* Font + Image Descriptor + Start of Image Data. 
 *
 * Font glyphs are black and white pixels making a 5x5 picture.
 * Each glyph has its own entry in array.
 * Pixels (White,White,Black,Black ...) are further compressed using LZW
 * compression.
 *
 * Next entry in array is Image Descriptor which is added before each glyph.
 * Last entry is start of Image Data.
 *
 * - "0" and comma are 7 and 5 bytes, but hacked to fill 8 bytes to make it 
 * easier to handle in minified code.
 * */
unsigned char r[][10]={
        /* Images representing glyphs. */
        { 4,   18, 150, 199, 188, 159, 10,  0}, /* 0 */
        { 4,   18, 102, 169, 188, 122, 64,  1}, /* 1 */
        { 68,  30, 160, 166, 104, 217, 80,  1}, /* 2 */
        { 68,  30, 160, 166, 184, 140, 66,  1}, /* 3 */
        { 68,  96, 153, 193, 135, 138, 66,  1}, /* 4 */
        { 68,  30,   6, 107, 199, 155, 80, 40}, /* 5 */
        { 68, 128, 150,  22, 173, 218, 90,  1}, /* 6 */
        { 68,  30, 160, 182, 169, 254, 84,  1}, /* 7 */
        { 68,  30,   6, 138, 153, 140, 10,  0}, /* 8 */
        { 68,  30,   6, 138, 185, 250, 66,  1}, /* 9 */
        {132, 143, 121, 177,  92,   0,  0,  0}, /* , (removed as not used) */
        {
        /* Image Descriptor */
        /* 0x2C    Image separator (Embedded in code)   */
           0,   /* Image Left   (LSB embedded in code.  */
        0, 0,   /* Image top    (16-bit Little endian)  */
        5, 0,   /* Image Width  (16-bit Little endian)  */
        5, 0,   /* Image Height (16-bit Little endian)  */
        0,      /* Packed byte  (Local color table (not used, etc.)) */
        /* Start of Image Data */
        2,      /* Starting size of LZW 2 + 1 = 3 */
        8       /* Number of bytes in data */
        }
};
/* GIF Header + Global Color table. 
 *
 * GIF's has a standard header.
 * Canvas size is the are on which to paint.
 * Usually this is size of whole image, but in this code I've spanned it out
 * and paint glyphs by rendering pictures on a canvas of size:
 * 20 * width_of_1_image (5 * 20 = 100)
 *
 * Each image can have an optional color table, but if not present the global
 * color table is used. In this code only global color table is used. It
 * consist of only black and white. (Though very easy to change if wanted.)
 * */
unsigned char buf[440] = {
        71, 73, 70,     /* Signature     "GIF" */
        56, 57, 97,     /* Version       "89a" */
        100, 0,         /* Canvas width  (16-bit Little endian) 5 * 20 = 100*/
          5, 0,         /* Canvas height (16-bit Little endian) 5 pixels.   */
        144,            /* Packed byte: 1 001 0 000
                                  1 : Has global color table.
                                001 : Color resolution.
                                  0 : Sorted Color Table (No)
                                000 : Size of Global Color table (2^(value+1))
                                        or 2 << value ...
                        */
        0,              /* Background Color index. */
        0,              /* Pixel aspect ratio. */
        /* Global color table. */
        255, 255, 255,  /* Index 0: White */
          0,   0,   0   /* Index 1: Black */
};

int main(void){
        /* PI generation variables. */
        int a = 10000, 
            b = 0,
            c = 70,
            d,
            e = 0,
            f[71],
            g;
        /* General purpose variables */
        int i,
            j,
            k = 18,     /* Current Index in out buffer. */
            s = 0;      /* Image counter:
                           (Tells us what "left/x" value should be). */
        char m[5];      /* Print next 4 digits of PI to this buffer. */
        /* Prepare / pre-fill for PI math. */
        for(;b < c;)
                f[b++] = a/5;
        /* Calculate 4 and 4 digits of PI and push onto out buffer. */
        for(; d = 0, g = c * 2; c -= 14 , e = d % a) { 
                for (b = c; d += f[b] * a, f[b] = d % --g, d /= g--, --b; d *= b);
                /* sprintf next 4 digits to temprary buffer.     */
                sprintf(m, "%d", e + d/a);
                /* We are served 4 and 4 digits. 
                 * Here we transalte them to glyphs and push onto out buffer*/
                for (i = 0; i < 4; ++i) {  
                        buf[++k] = 0x2C;     /* 0x2C : Image separator.        */
                        buf[++k] = s++ * 5;  /* xx   : Image left (x) on canvas.*/
                        for (j = 0; j < 10; ++j) {
                                /* Push "Start of Image Data" onto buffer      */
                                buf[++k] = r[11][j];
                        }
                        for (j = 0; j < 8; ++j) {
                                /* Push data of glyph (LZW-compressed) onto buffer. */
                                buf[++k] = r[m[i]-'0'][j];
                        }
                        /* Start of image data informs how big the image data 
                         * is. End with zero to mark that this is EOI. */
                        buf[++k] = 0;       
                }
        }
        /* 0x3b is Trailer, marking end of file. */
        buf[k] = 0x3b;
        /* Write buffer to standard output. 
         * 'k' holds length of data, though as we know this image is 
         * 100x5 etc. we can pre-define it as well.
         * */
        fwrite(buf, 1, k, stdout);
}

π를 계산하기 위해 더 짧거나 다른 알고리즘을 사용하려고합니다.


2
이미지에서 처음 3 뒤에 점이 표시되지 않습니다.
Victor Stafusa

1
파이 10 진수 생성 알고리즘에 대한 정보 링크가 있습니까? 나는 당신의 코드를 약간 가지고 놀았지만 (Gif 내용을 제거한 후에) 그것이 숫자의 숫자로 나타나는지 모르겠다 .
FireFly

7

자바 스크립트, 680 자

<html><body></body><script>v=["","41L70L7e","24C223060Ca0b587C592b2eLae","30L90L55L65C95a7a9Cac9e6eC5e3e2c","aaL2aL80L8e","90L40L36C455565C95a7a9Cac9e6eC5e3e2c","70C52272aC2c3e6eC9eacaaCa89666C36282a","20La0C745a5e","60C202435C465666C96a8aaCac9e6eC3e2c2aC283666C768695Ca4a060","a4Ca69868C382624C223060C90a2a4Ca77c5e","6dC7d7e6eC5e5d6d"];v["."]=v[10];a=(""+(4*Math.atan(1))).split("");s="";for(i in a)s+="<path d='M "+v[a[i]].split("").map(function(c){return+-c||c>"Z"?parseInt(c,16):c;}).join(" ")+"'transform='translate("+i*33+".5,10.5)scale(3,3)'fill='none'stroke='#333'stroke-linecap='round'stroke-linejoin='round'/>";document.body.innerHTML="<svg>"+s+"</svg>";</script></html>

이것은 웹 브라우저에서 볼 수 있습니다. 숫자는 SVG 경로로 출력됩니다.

웹 브라우저에서 SVG 출력 스크린 샷

  • 흥미로운 방식으로 pi를 계산하지 않으며 JS에는 20 자리를 표시하는 정밀도가있는 숫자 유형이 없습니다.

  • 문자를 저장하기 위해 시퀀스에 표시되지 않기 때문에 "0"에 대한 경로 데이터를 생략했습니다.


벡터 기반 접근 방식입니다. 글꼴에 대해서도 매우 훌륭하고 훌륭합니다.
FireFly

5

자바 - 866 860 857 853 문자, 플러스 574 개 문자와 바람을 피우고 버전

1996 년 Simon Plouffe 공식을 사용하여 x.png검정색 배경에 흰색 디지털 시계와 같은 숫자가있는 파일을 출력합니다 .

파이

이것은 압축 된 코드입니다.

import java.math.BigDecimal;class E{static java.awt.Graphics g;public static void main(String[]h)throws Exception{java.awt.image.BufferedImage i=new java.awt.image.BufferedImage(213,17,1);g=i.getGraphics();BigDecimal y=v(-3);for(int n=1;n<99;n++)y=y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2*n),42,0));int j=2;for(char c:y.toPlainString().substring(0,21).toCharArray()){if(j!=12){c-=48;boolean b=c!=1&c!=4;t(b,j,2,8,3);t(c<1|c>3&c!=7,j,2,3,8);t(c<5|c>6,j+5,2,3,8);t(c>1&c!=7,j,7,8,3);t(c%2==0&b,j,7,3,8);t(c!=2,j+5,7,3,8);t(b&c!=7,j,12,8,3);}j+=10;}t(true,17,12,3,3);javax.imageio.ImageIO.write(i,"png",new java.io.File("x.png"));}static BigDecimal v(int k){return BigDecimal.valueOf(k);}static BigDecimal f(int k){return k<2?v(1):f(k-1).multiply(v(k));}static void t(boolean x,int a,int b,int c,int d){if(x)g.fillRect(a,b,c,d);}}

즉, 식별과 공백은 다음과 같습니다.

import java.math.BigDecimal;

class E {

    static java.awt.Graphics g;

    public static void main(String[] h) throws Exception {
        java.awt.image.BufferedImage i = new java.awt.image.BufferedImage(213, 17, 1);
        g = i.getGraphics();
        BigDecimal y = v(-3);

        // Calculate PI using the Simon Plouffe formula, 1996.
        for (int n = 1; n < 99; n++)
            y = y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2 * n), 42, 0));

        int j = 2;
        for (char c : y.toPlainString().substring(0, 21).toCharArray()) {
            if (j != 12) {
                c -= 48;
                boolean b = c != 1 & c != 4;
                t(b, j, 2, 8, 3);
                t(c < 1 | c > 3 & c != 7, j, 2, 3, 8);
                t(c < 5 | c > 6, j + 5, 2, 3, 8);
                t(c > 1 & c != 7, j, 7, 8, 3);
                t(c % 2 == 0 & b, j, 7, 3, 8);
                t(c != 2, j + 5, 7, 3, 8);
                t(b & c != 7, j, 12, 8, 3);
            }
            j += 10;
        }
        t(true, 17, 12, 3, 3);
        javax.imageio.ImageIO.write(i, "png", new java.io.File("x.png"));
    }

    static BigDecimal v(int k) {
        return BigDecimal.valueOf(k);
    }

    static BigDecimal f(int k) {
        return k < 2 ? v(1) : f(k - 1).multiply(v(k));
    }

    static void t(boolean x, int a, int b, int c, int d) {
        if (x) g.fillRect(a, b, c, d);
    }
}

규칙을 부정하고 PI 계산이 "문자열 3.1415926535897934384의 숫자 표현"으로 수행 될 수 있다고 생각하면이를 574 자로 줄일 수 있습니다.

class F{static java.awt.Graphics g;public static void main(String[]h)throws Exception{java.awt.image.BufferedImage i=new java.awt.image.BufferedImage(213,17,1);g=i.getGraphics();int j=2;for(char c:"3.1415926535897932384".toCharArray()){if(j!=12){c-=48;boolean b=c!=1&c!=4;t(b,j,2,8,3);t(c<1|c>3&c!=7,j,2,3,8);t(c<5|c>6,j+5,2,3,8);t(c>1&c!=7,j,7,8,3);t(c%2==0&b,j,7,3,8);t(c!=2,j+5,7,3,8);t(b&c!=7,j,12,8,3);}j+=10;}t(true,17,12,3,3);javax.imageio.ImageIO.write(i,"png",new java.io.File("x.png"));}static void t(boolean x,int a,int b,int c,int d){if(x)g.fillRect(a,b,c,d);}}

4

자바 - 642 622 자

1996의 Simon Plouffe 공식을 사용하여 이전 답변에서 복사했습니다. 그러나 대신 ASCII 아트를 출력합니다.

import java.math.BigDecimal;class H{public static void main(String[]h)throws Exception{int[]t={31599,4681,31183,29647,5101,29671,31719,4687,31727,29679,8192};BigDecimal y=v(-3);for(int n=1;n<99;n++)y=y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2*n),42,0));for(int z=0;z<5;z++){for(char c:y.toPlainString().substring(0,21).toCharArray()){if(c<48)c=58;int a=(t[c-48]>>>z*3)&7;e(a/4);e(a/2&1);e(a&1);e(0);e(0);}e(10);}}static void e(int c){System.out.print((char)(c<2?c*3+32:c));}static BigDecimal v(int k){return BigDecimal.valueOf(k);}static BigDecimal f(int k){return k<2?v(1):f(k-1).multiply(v(k));}}

이 모든 것에는 약간의 식별과 공백이 있으며 독자에게 약간의 도움이 주어 마법의 숫자의 의미를 이해합니다.

import java.math.BigDecimal;

class H {

    public static void main(String[] h) throws Exception {
        // Each block corresponds to a line. Each char has 5 lines with a 3-char width.
        int[] t = {
            0b111_101_101_101_111,
            0b001_001_001_001_001,
            0b111_100_111_001_111,
            0b111_001_111_001_111,
            0b001_001_111_101_101,
            0b111_001_111_100_111,
            0b111_101_111_100_111,
            0b001_001_001_001_111,
            0b111_101_111_101_111,
            0b111_001_111_101_111,
            0b010_000_000_000_000
        };

        // Calculate PI using the Simon Plouffe formula, 1996.
        BigDecimal y = v(-3);
        for (int n = 1; n < 99; n++)
            y = y.add(v(n).multiply(v(2).pow(n)).multiply(f(n).pow(2)).divide(f(2 * n), 42, 0));

        for (int z = 0; z < 5; z++) {
            for (char c : y.toPlainString().substring(0, 21).toCharArray()) {
                if (c < 48) c = 58;
                int a = (t[c - 48] >>> z * 3) & 7;
                e(a / 4);
                e(a / 2 & 2);
                e(a & 1);
                e(0);
                e(0); // Not needed, but makes a better art with the cost of 5 chars.
            }
            e(10);
        }
    }

    static void e(int c) {
        System.out.print((char) (c < 2 ? c * 3 + 32 : c));
    }

    static BigDecimal v(int k) {
        return BigDecimal.valueOf(k);
    }

    static BigDecimal f(int k) {
        return k < 2 ? v(1) : f(k - 1).multiply(v(k));
    }
}

산출:

###         #  # #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  # #  
  #         #  # #    #  #    # #    #  #    #      #  #    # #  # #    #  # #    #    #    #  # #  # #  
###         #  ###    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###  ###  
  #         #    #    #    #    #  #    # #    #    #    #  # #    #    #    #    #  #      #  # #    #  
###   #     #    #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###    # 

4

C, 253250

@Sukminder 코드의 알고리즘을 사용하여 대략적으로 pi를 계산합니다 (코드를 약간 빌려서 리팩토링). 예를 들어 ImageMagick으로 변환 할 수 있는 이진 PBM 이미지를 출력합니다 .

b,c=70,e,f[71],g;v[71],j,k;L[5]={1072684944,792425072,492082832,256581624};
main(d){for(puts("P4\n8 100");b<c;)f[b++]=2;for(;d=0,g=--c*2;e=d%10){
for(b=c;d+=f[b]*10,f[b]=d%--g,d/=g--,--b;d*=b);v[j++]=e+d/10;}
for(;k<100;k++)putchar(L[k%5]>>3*v[k/5]&7);}

점자 기반 PPM 렌더러의 출력 결과는 다음과 같습니다.

출력 스크린 샷

소수점 구분 기호가 없다는 점에서 @Sukminder의 대답과 동일한 단점이 있습니다. 또한 내 출력은 수직이며 사람이 읽을 수 있는지 여부는 논쟁의 여지가 있습니다 ...

편집 : @ugoren의 제안을 적용했습니다.


작은 개선 사항 : 이동 putsfor 초기화, 정의 L[5]와 생략 ,0. 확인 d에 매개 변수 main(쉼표 저장).
우고 렌

4

PHP 380

이미지 출력을 위해 gd 활성화 필요

<? header('Content-Type: image/png');$i=imagecreatetruecolor(84,5);$n=['71775777770','51115441550','51777771770','51411151510','71771771712'];$c=imagecolorallocate($i,255,255,255);$m=(6.28318/2).(5307*5).(28060387*32);$k=5;while($k--)for($j=0;$j<21;$j++){$p=str_pad(decbin($n[$k][($m[$j]!='.')?$m[$j]:10]),3,'0',0);$l=3;while($l--)$p[$l]&&imagesetpixel($i,$l+$j*4,$k,$c);}imagepng($i);

여기에 이미지 설명을 입력하십시오

pi 계산 : 기본 PHP의 기본 정밀도는 14이며 임의 정밀도 확장을 사용하여 서버를 다시 컴파일하고 싶지 않기 때문에 필요한 소수로 PI를 근접시킬 수 없으므로 대신 tau / 2를 계산 한 다음 나머지 소수

그래픽은 0과 1로 구성되어 있기 때문에 나중에 gd를 제거 할 수 있는지 확인하기 위해 WBMP를 형식으로 사용해 볼 수 있습니다.


그 이미지는 검은 색은 빨간색이고 실제로 작지만 500 %이면 가까이서 보면 읽을 수 있습니다. (그리고 색맹되지 않습니다.)
hildred

@hildred 각 문자는 3x5 with 1 px between chars입니다. 색상은 빨간색으로 4 글자를 줄 였지만 이길 수 없다는 점을 고려하여 가독성을 위해 흰색으로 변경합니다.
Einacio

저의 의견은 비판이 아니라 설명을 위해 표를 올리는 것이 었습니다.
초에 hildred

imagecreateindex가 문자를 저장합니까? 그러한 기능이 존재합니까?
33 초에 숨겨 짐

팔레트 이미지 ( imagecreate)로 작업 할 때 첫 번째 호출은 imagecolorallocate배경색 을 설정하고 , 두 번째 호출은 쓰기 색을 설정하는 데 필요합니다. 그래서 더 이상 끝
Einacio

4

C + LaserWriter 프린터 599-10 = 589

출력을 LaserWriter로 파이프하십시오! :) 이것은 Lisa (C 컴파일러 사용)에서 작동해야합니다.

이 계산 pi직경으로 나눈 반원에 가까운 베 지어 곡선 시퀀스 근사 라인 세그먼트, 2 배의 길이의 합을 산출하여 프린터.

main(){
printf("/dist{dtransform dup mul exch dup mul add sqrt}def");
printf("/len{3 2 roll sub 3 1 roll exch sub dist}def");
printf("/pi{0 0 2 index 0 180 arc closepath flattenpath");
printf("[{2 copy}{2 copy 6 2 roll len 3 1 roll}{}{counttomark -2 roll len\n");
printf("counttomark 2 add 1 roll counttomark 1 sub{add}repeat\n");
printf("exch pop exch pop exch div 2 mul}pathforall}def\n");
printf("matrix setmatrix 100 dup scale 10 setflat 100 pi 10 string cvs\n");
printf("matrix defaultmatrix setmatrix/Palatino-Roman findfont 10 scalefont setfont\n");
printf("100 700 moveto show showpage");
}

Ungolfed Level-1 (1985 호환) PostScript :

%!
/dist { % dx dy  .  dz  
    dtransform
    dup mul exch dup mul add sqrt
} def 

/len { % x1 y1 x2 y2  .  dist(y2-y1,x2-x1)
    3 2 roll % x1 x2 y2 y1
    sub 3 1 roll exch sub % y2-y1 x2-x1
    dist
} def 

/pi { % rad 
    0 0 2 index 0 180 arc closepath % rad 
    flattenpath
    [   
    { % rad [ x(0) y(0)     (m)print
        2 copy 
    } %moveto proc
    { % rad [ ... x(n-1) y(n-1) x(n) y(n)     (l)print
        2 copy 6 2 roll len % rad [ ... x(n) y(n) dist
        3 1 roll % rad [ ... dist x(n) y(n)
    } %lineto proc
    {} %curveto proc % n.b. flattenpath leaves no curve segments
    { % rad [ x(0) y(0) dist(1) dist(2) ... dist(n-1) x(n) y(n)     (c)print
        counttomark -2 roll len % rad [ dist(1) dist(2) ... dist(n)
        counttomark 2 add 1 roll % dist(n) rad [ dist...
        counttomark 1 sub { add } repeat % dist(n) rad [ sum_dist
        exch pop % dist(n) rad sum_dist
        exch pop % dist(n) sum_dist
        exch % sum_dist dist(n)
        div  % length_of_half_circle/diameter
        2 mul % C/d 
    } %closepath proc
    pathforall
} def 

matrix setmatrix
100 dup scale
10 setflat
100 pi 10 string cvs 
matrix defaultmatrix setmatrix
/Palatino-Roman findfont 10 scalefont setfont
100 700 moveto show

산출:

ps_pi


나는 또한 글꼴을 만들어야한다고 가정합니다.
luser droog

흠. 이런 식으로 충분한 숫자를 얻지 못할 것입니다. PS에는 32 비트 플로트 만 있습니다.
luser droog

멋진 아이디어, 나는 골프를위한 포스트 스크립트를 좋아한다.
숨겨 짐

나는 숫자에 대한 비트 맵 글꼴을 가지고 있지만 골프는 그것을 망칠 것입니다!
luser droog

2

Java, 1574 2643 1934 자

압축 된 1934 자 :

    public static void main(String[] args){int[][][]num={{{1,1,1},{1,0,1},{1,0,1},{1,0,1},{1,1,1}},{{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1}},{{1,1,1},{0,0,1},{1,1,1},{1,0,0},{1,1,1}},{{1,1,1},{0,0,1},{1,1,1},{0,0,1},{1,1,1}},{{1,0,1},{1,0,1},{1,1,1},{0,0,1},{0,0,1}},{{1,1,1},{1,0,0},{1,1,1},{0,0,1},{1,1,1}},{{1,1,1},{1,0,0},{1,1,1},{1,0,1},{1,1,1}},{{1,1,1},{0,0,1},{0,0,1},{0,0,1},{0,0,1}},{{1,1,1},{1,0,1},{1,1,1},{1,0,1},{1,1,1}},{{1,1,1},{1,0,1},{1,1,1},{0,0,1},{0,0,1}},{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,1}}};BufferedImage image=new BufferedImage(103,5,BufferedImage.TYPE_3BYTE_BGR);for(int q=0;q<103;q++){for(int w=0;w<5;w++){image.setRGB(q,w,0xFFFFFF);}}int loc = 0;String g=String.valueOf(pi(20));for(int w=0;w<g.length()-1;w++){Integer n=0;if(g.charAt(w)=='.'){n=10;}else{n=Integer.parseInt(String.valueOf(g.charAt(w)));}for(int t=0;t<5;t++){for(int q=0;q<3;q++){int c=num[n][t][q]==1?0x000000:0xFFFFFF;image.setRGB(loc+q,t,c);}}loc+=5;}try{BufferedImage bi=image;File f=new File("o.png");ImageIO.write(bi,"png",f);}catch(IOException e){}}public static BigDecimal pi(final int SCALE){BigDecimal a=BigDecimal.ONE;BigDecimal b=BigDecimal.ONE.divide(sqrt(new BigDecimal(2),SCALE),SCALE,BigDecimal.ROUND_HALF_UP);BigDecimal t=new BigDecimal(0.25);BigDecimal x=BigDecimal.ONE;BigDecimal y;while(!a.equals(b)){y=a;a=a.add(b).divide(new BigDecimal(2),SCALE,BigDecimal.ROUND_HALF_UP);b=sqrt(b.multiply(y),SCALE);t=t.subtract(x.multiply(y.subtract(a).multiply(y.subtract(a))));x=x.multiply(new BigDecimal(2));}return a.add(b).multiply(a.add(b)).divide(t.multiply(new BigDecimal(4)),SCALE,BigDecimal.ROUND_HALF_UP);}public static BigDecimal sqrt(BigDecimal A,final int SCALE){BigDecimal x0=new BigDecimal("0");BigDecimal x1=new BigDecimal(Math.sqrt(A.doubleValue()));while(!x0.equals(x1)){x0=x1;x1=A.divide(x0,SCALE,BigDecimal.ROUND_HALF_UP);x1=x1.add(x0);x1=x1.divide(new BigDecimal(2),SCALE,BigDecimal.ROUND_HALF_UP);}return x1;}}

확장 된 2643 자 :

public static void main(String[] args) {
    int[][][] num = { { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 } },
            { { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 } },
            { { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 } },
            { { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } },
            { { 1, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 } },
            { { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 1 }, { 1, 1, 1 } },
            { { 1, 1, 1 }, { 1, 0, 0 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } },
            { { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 }, { 0, 0, 1 } },
            { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } },
            { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 1 } },
            { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 1 } } };

    BufferedImage image = new BufferedImage(103, 5, BufferedImage.TYPE_3BYTE_BGR);

    for (int q = 0; q < 103; q++) {
        for (int w = 0; w < 5; w++) {
            image.setRGB(q, w, 0xFFFFFF);
        }
    }

    int loc = 0;

    String g = String.valueOf(pi(20));
    for (int w = 0; w < g.length()-1; w++) {
        Integer n = 0;
        if (g.charAt(w) == '.') {
            n = 10;
        } else {
            n = Integer.parseInt(String.valueOf(g.charAt(w)));
        }
        for (int t = 0; t < 5; t++) {
            for (int q = 0; q < 3; q++) {
                int c = num[n][t][q] == 1 ? 0x000000 : 0xFFFFFF;
                image.setRGB(loc + q, t, c);
            }
        }
        loc += 5;
    }
    try {
        BufferedImage bi = image;
        File outputfile = new File("out2.png");
        ImageIO.write(bi, "png", outputfile);
    } catch (IOException e) {

    }
}

public static BigDecimal pi(final int SCALE) {
    BigDecimal a = BigDecimal.ONE;
    BigDecimal b = BigDecimal.ONE.divide(sqrt(new BigDecimal(2), SCALE), SCALE, BigDecimal.ROUND_HALF_UP);
    BigDecimal t = new BigDecimal(0.25);
    BigDecimal x = BigDecimal.ONE;
    BigDecimal y;

    while (!a.equals(b)) {
        y = a;
        a = a.add(b).divide(new BigDecimal(2), SCALE, BigDecimal.ROUND_HALF_UP);
        b = sqrt(b.multiply(y), SCALE);
        t = t.subtract(x.multiply(y.subtract(a).multiply(y.subtract(a))));
        x = x.multiply(new BigDecimal(2));
    }
    return a.add(b).multiply(a.add(b)).divide(t.multiply(new BigDecimal(4)), SCALE, BigDecimal.ROUND_HALF_UP);

}

public static BigDecimal sqrt(BigDecimal A, final int SCALE) {
    BigDecimal x0 = new BigDecimal("0");
    BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
    while (!x0.equals(x1)) {
        x0 = x1;
        x1 = A.divide(x0, SCALE, BigDecimal.ROUND_HALF_UP);
        x1 = x1.add(x0);
        x1 = x1.divide(new BigDecimal(2), SCALE, BigDecimal.ROUND_HALF_UP);
    }
    return x1;
}

파이 방법은 /programming/8343977/calculate-pi-on-an-android-phone?rq=1 에서 수집했습니다.


PI를 계산하는 대신 상수를 사용한 것 같습니다.
hildred

그것은 좋은 비틀기입니다. 지금 작업 중입니다.
Clayton

당신은 추가하여 좀 더 그것을 압축 할 수 있습니다 throws Exceptionmain와 try-catch 블록을 제거. 또한, 이름 바꾸기 수 pisqrt방법과 loc, args, SCALE, x0x11 숯 식별자 변수. 그리고 당신은 완전한 클래스를 추가 해야하는 방법으로class Foo{ 선언 및 가져 오기가 포함됩니다.
Victor Stafusa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.