hạn chế ngu ngốc và sa mạc


18

Vì vậy, bạn đang ngồi ở bàn làm việc, chơi một chương trình để tính 20 chữ số đầu tiên của pi, và cùng với ông chủ của bạn và ném quả táo IIe của bạn ra ngoài cửa sổ. Bây giờ bạn đang làm việc trên một dự án mới và máy tính này chưa có bất kỳ khả năng văn bản nào. Không ai. Không có phông chữ. Không có gì.

Bây giờ hãy hoàn thành chương trình đó. Tính toánhiển thị 20 ký tự đầu tiên của pi mà không sử dụng bất kỳ phông chữ nào không phải là một phần của chương trình của bạn. Đầu ra của bạn có thể được hiển thị hoặc ghi thành tiêu chuẩn dưới dạng tệp hình ảnh (jpeg, png, gif, svg (miễn là bạn không sử dụng bất kỳ ký tự nào), bmp, xpm). Bạn có thể sử dụng bất kỳ ngôn ngữ nào, nhưng bạn không thể sử dụng các chức năng phông chữ, hiển thị văn bản hoặc tương tự.

phần thưởng nhỏ (10 ký tự) Nếu nó hoạt động trên Lisa.

Chỉnh sửa: đối với những người không tìm ra cảm hứng của tôi là máy mac đầu tiên và tiêu đề là một cách chơi chữ. Một danh tiếng lớn cho @Sukminder có gif hoạt hình thật tuyệt. Cuộc thi sẽ không kết thúc nếu có câu trả lời hay hơn.


Tôi thích thử thách, nhưng về mặt kỹ thuật, một hệ thống như vậy cũng không có khả năng hiển thị mã nguồn? Ngoại trừ Piet, tất nhiên.
Tiếp

2
@ValekHalfHeart bạn có thể tải mã nguồn từ một máy khác
John Dvorak

1
Và làm thế nào để bạn xác định con người có thể đọc được? Ví dụ, chữ viết tay của tôi có thể đọc được đối với một số người (ít nhất là một) và không phải cho người khác. (Nhân tiện, 2 ^ (2x2) = 16, đủ glyphs cho tất cả 11 chữ số.))
Kendall Frey

4
Tôi hoàn toàn không hiểu tiêu đề, tôi không hiểu làm thế nào nghệ thuật ASCII có thể ổn khi chúng ta không thể sử dụng hiển thị văn bản và câu hỏi rất cần một định nghĩa về "tính PI".
Peter Taylor

2
"Tính pi" thực sự có nghĩa là gì? Tôi có thể mã hóa một bitmap của 20 số thập phân đầu tiên không? (Không sử dụng bất kỳ PI tích hợp hoặc tương tự)
FireFly

Câu trả lời:


6

Python, 222 ký tự

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)

Dòng đầu tiên tính các chữ số của pi bằng cách sử dụng xấp xỉ pi-3 ~= 277991633/1963319607. Ba dòng tiếp theo xuất ra 20 ký tự pi sử dụng nghệ thuật chữ nổi Nemeth ASCII .

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

Tôi đang đẩy các ranh giới theo hai hướng ở đây, cả về cảm giác "tính toán Pi" và "con người có thể đọc được".


3
Cái quái gì thế Tôi nghĩ rằng chúng tôi không nên sử dụng bất kỳ đầu ra văn bản. Làm thế nào máy tính của bạn sẽ hiển thị các *không gian và không có phông chữ?
gian hàng

@boothby: Đó là nghệ thuật ASCII. Hãy nghĩ về *pixel đen 1x1 và `` như pixel trắng 1x1.
Keith Randall

1
Anh ấy có một điểm. Bạn không thể kết xuất *mà không sử dụng phông chữ, tôi nghĩ bạn không đủ tiêu chuẩn
Sirens

18

Python, 217 byte

Yêu cầu Thư viện hình ảnh Python

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

Số byte giả định rằng ký tự thoát \177được thay thế bằng ký tự tương đương (char 127 ).

Đầu ra sẽ xuất hiện như sau (nó sẽ mở trong trình xem * .bmp mặc định của bạn):

Lưu ý rằng điều này có thể dễ dàng được tham số hóa để in bất kỳ số chữ số nào bạn muốn. Sau đây sẽ chấp nhận một đầu vào số nguyên từ stdin và hiển thị nhiều chữ số:

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

Đầu ra cho n = 80 :


Tính toán Pi

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

Đúng rồi, thế đó. Công thức được sử dụng là kết quả của việc áp dụng Biến đổi của Euler cho Sê-ri Leibniz , và sau đó bao gồm từng thuật ngữ từ phần còn lại của tổng. Công thức hội tụ tuyến tính; mỗi chữ số yêu cầu log 2 (10) ≈ 3,32 lần lặp. Đối với những người quan tâm đến việc phái sinh, xem Phụ lục A.

Trưng bày

PIL được sử dụng để tạo hình ảnh, bởi vì đó là thư viện thuận tiện nhất mà tôi biết. Một bitmap trắng đen 141 × 11 trống được tạo ra, và sau đó các đường trắng được vẽ trên đó theo kiểu bảy đoạn, mỗi pixel một pixel. Các vị trí cần thiết để vẽ mỗi phân đoạn được lưu trữ trong chuỗi bitmask, với các bit tương ứng với các vị trí sau:

 000
3   5
3   5
 111
4   6
4   6
 222

Bit ma thuật (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)tạo ra từng pixel theo thứ tự sau (cơ sở-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

Phụ lục A

Biến đổi Euler là một kỹ thuật tăng tốc hội tụ, hoạt động cho bất kỳ chuỗi nào hiển thị sự hội tụ đơn điệu tuyệt đối. Chuỗi kết quả sẽ hội tụ tuyến tính, thường ở tốc độ một bit trên mỗi số hạng (lưu ý rằng nếu chuỗi gốc đã siêu tuyến tính, chuỗi kết quả sẽ thực sự hội tụ chậm hơn). Các mô tả thuần túy toán học là một chút khó khăn để làm theo, vì vậy tôi sẽ được tham gia một cách tiếp cận thủ tục.

Chúng ta sẽ bắt đầu với Leibniz Series:

Sau đó chia mỗi thuật ngữ thành một nửa, kết hợp các thuật ngữ lân cận:

Giản thể:

Tổng quát:

Lưu ý rằng hàng đầu ½ không có điều khoản đối tác và do đó đã bị loại trừ khỏi phần còn lại của khoản tiền. Đây là thuật ngữ đầu tiên của loạt chuyển đổi. Để tìm thuật ngữ tiếp theo, chúng tôi lặp lại quy trình một lần nữa:

Và một lần nữa:

Và một lần nữa:

Và một lần nữa cho các biện pháp tốt:

Tại thời điểm này, chúng tôi có năm điều khoản đầu tiên, và nhiệm kỳ thứ sáu là hiển nhiên. Điều này là đủ để khái quát, vì vậy chúng tôi sẽ dừng ở đây. Chúng ta sẽ bắt đầu bằng cách bao thanh toán tử số và mẫu số:

Các mẫu số rõ ràng chứa Nhân tố kép2n + 1 , vì vậy chúng tôi sẽ vá nó trong:

Phù hợp tất cả mọi thứ, trừ hai nhiệm kỳ đầu tiên mà có một mất tích 2 ở mẫu số. Chúng ta có thể khắc phục điều đó bằng cách nhân toàn bộ biểu thức với 2 :

2 3 = 2 · 4 , vì vậy:

Tử số bây giờ có thể dễ dàng được xác định là n! .

Lưu ý rằng yếu tố được thêm vào mỗi thuật ngữ liên tiếp, n / (2n + 1) , tiếp cận ½ khi n trở nên lớn, ngụ ý sự hội tụ tuyến tính với tốc độ một bit trên mỗi thuật ngữ - thực tế là do thiết kế. Một kết quả tốt, nhưng nó thậm chí còn đẹp hơn nếu không có các yếu tố trong đó. Những gì chúng ta có thể làm ở đây là tính ra từng thuật ngữ liên tiếp từ phần còn lại của tổng, điều này sẽ tạo ra một biểu thức lồng nhau:



Điều này có thể được viết lại như một mối quan hệ lặp lại:

Trong đó n đếm ngược từ ⌈ log 2 (10) · d ⌉ .. 0 , trong đó d là số chữ số cần thiết.

Thật thú vị khi lưu ý rằng điểm ổn định của sự tái phát này chính xác là 2 (hoặc 4 nếu bạn đã nhân đôi nó, như tôi đã nói ở phần cấy ghép ở trên), vì vậy bạn có thể lưu một số lần lặp bằng cách khởi tạo đúng cách. Mặc dù, việc khởi tạo một giá trị ngẫu nhiên mà bạn cần ở nơi khác và ném thêm một vài lần lặp lại trên đầu thường là byte khôn ngoan hơn.


1
Rất hay, cảm ơn vì bài học! Những gì tôi không nhận được là những gì ptrong p/2 * x/p + ...đang làm .. AIUI Python hỗ trợ xúc tiến tự động để một datatype BigInteger-ish, vì vậy nó không phải là một điều chính xác, nhưng bằng cách nào đó những plà vật chất và không hủy bỏ ra như tôi tưởng tượng Họ ... tôi đang thiếu gì ở đây?
FireFly

@FireFly pkhởi tạo lẻ, do đó, p/2/ptương đương - dưới phép chia số nguyên - thành ((p-1)/2)/p. Điều này tạo ra 1/3, 2/5, 3/7vv thuật ngữ có nguồn gốc ở trên.
primo

12

#C - 777 ký tự

C - 731 Nhân vật

In GIF sang stdout.

  • Quirk: Không có dấu phẩy sau đầu tiên 3.

Ghép các GIF lại với nhau từ tiêu đề được cấu hình sẵn + mỗi chữ số được biểu thị bằng phông chữ pha trộn tại nhà (nhúng) 5x5 pixel.

Kết quả

nhập mô tả hình ảnh ở đây

Nó đây rồi --- ^

Lưu ý rằng GIF biến mất, đôi khi, trong Chrome sau một lần chạy.

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

Giới thiệu ngắn:

Tính toán PI

Pi được tính toán bằng cách sử dụng một phiên bản sửa đổi một chút của Dik Winter và Achim Flammenkamp khi thực hiện thuật toán Rabinowitz và Wagon để tính toán các chữ số của π.

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

Thế hệ GIF

Hình ảnh GIF có một canvastài sản trong tiêu đề. Chúng ta có thể sử dụng kết hợp với hiển thị nhiều hình ảnh bằng cách đặt thuộc lefttính cho từng chữ số tương ứng - trong đó mỗi chữ số là một hình ảnh (được nhúng).

Tài liệu.

Thí dụ:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

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

Mã mở rộng (với vô số ý kiến)

Lộn xộn, nhưng đó là một phần của việc giảm thiểu :

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

Tìm cách sử dụng thuật toán ngắn hơn / khác để tính toán π.


2
Tôi không thấy dấu chấm sau 3 hình đầu tiên.
Victor Stafusa

1
Bạn có một liên kết đến thông tin về thuật toán tạo số thập phân pi không? Tôi đã chơi xung quanh với mã của bạn một chút (sau khi loại bỏ các công cụ GIF), nhưng tôi thực sự không hiểu tại sao nó lại dẫn đến các chữ số của pi ...
FireFly

7

JavaScript, ký tự 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>

Điều này có thể được xem trong một trình duyệt web; các số được xuất ra dưới dạng đường dẫn SVG.

Ảnh chụp màn hình đầu ra SVG trong trình duyệt web

  • Nó không tính toán pi theo một cách thú vị và JS thiếu một loại số với độ chính xác để hiển thị 20 chữ số.

  • Để lưu các ký tự, tôi đã bỏ qua dữ liệu đường dẫn cho "0", vì nó không hiển thị trong chuỗi.


Ooh, một cách tiếp cận dựa trên vector. Rất đẹp, công việc tốt về phông chữ quá.
FireFly

5

Java - 866 860 857 853 ký tự, cộng với phiên bản gian lận với 574 ký tự

Sử dụng công thức Simon Plouffe từ năm 1996, xuất ra một x.pngtệp có các số giống như đồng hồ kỹ thuật số màu trắng trong nền đen:

số Pi

Đây là mã nén:

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

Điều đó, với nhận dạng và một số khoảng trắng sẽ là:

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

Gian lận các quy tắc và xem xét rằng việc tính toán PI có thể được thực hiện dưới dạng "biểu diễn số của Chuỗi 3.1415926535897934384", điều này có thể giảm xuống còn 574 ký tự:

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

Java - 642 622 ký tự

Sao chép từ câu trả lời trước của tôi, sử dụng công thức Simon Plouffe từ năm 1996. Nhưng thay vào đó, xuất ra nghệ thuật 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));}}

Tất cả điều đó, với một số nhận dạng và không gian, và một chút giúp đỡ người đọc hiểu ý nghĩa của các con số ma thuật:

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

Đầu ra:

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

4

C, 253 250 ký tự

Xấp xỉ pi bằng cách sử dụng thuật toán trong mã của @ Sukminder (mượn một cách đáng xấu hổ và tái cấu trúc mã của họ một chút). Xuất ra hình ảnh PBM nhị phân , sau đó có thể được chuyển đổi bằng ImageMagick.

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

Đây là kết quả đầu ra trông như thế nào với trình kết xuất PPM dựa trên chữ nổi của tôi:

Ảnh chụp màn hình đầu ra

Có cùng một câu trả lời như câu trả lời của @ Sukminder ở chỗ nó thiếu dấu phân cách thập phân. Ngoài ra, đầu ra của tôi là thẳng đứng, và liệu nó có thể đọc được bằng con người hay không ...

Chỉnh sửa: áp dụng đề xuất của @ ugoren.


Cải tiến nhỏ: chuyển putssang for khởi tạo, xác định L[5]và bỏ qua ,0. Tạo dmột tham số để main(lưu dấu phẩy).
ugoren

4

PHP 380

yêu cầu gd kích hoạt cho đầu ra hình ảnh

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

nhập mô tả hình ảnh ở đây

Tính toán pi: vì php cơ sở có độ chính xác mặc định là 14 và tôi không muốn biên dịch lại máy chủ với các phần mở rộng độ chính xác tùy ý được kích hoạt, tôi thậm chí không thể ước lượng PI với số thập phân cần thiết, vì vậy thay vào đó, nó tính toán tau / 2 và sau đó phần còn lại của số thập phân

vì đồ họa được tạo từ 0 và 1, tôi có thể thử sử dụng WBMP làm định dạng sau để xem liệu tôi có thể xóa gd không


hình ảnh đó có màu đỏ trên nền đen và rất nhỏ, nhưng ở mức 500% bạn có thể đọc nó nếu bạn nhìn gần. (và không bị mù màu.)
hildred

@hildred mỗi nhân vật là 3x5 with 1 px between chars. màu đỏ chỉ để giảm 4 ký tự, nhưng xem xét rằng tôi sẽ không thắng, tôi sẽ đổi nó thành màu trắng để dễ đọc
Einacio

Nhận xét của tôi không nhằm mục đích chỉ trích, mà là một lời giải thích, để khuyến khích bỏ phiếu.
hildred

Imagecreateindex sẽ lưu bất kỳ ký tự nào? chức năng như vậy có tồn tại?
hildred

@hildred khi làm việc với một hình ảnh pallete ( imagecreate), lần gọi đầu tiên của việc imagecolorallocateđặt màu nền và một cái thứ hai là cần thiết để đặt màu viết. vì vậy nó kết thúc lâu hơn
Einacio

4

Máy in C + LaserWriter 599 - 10 = 589

Đặt đầu ra cho LaserWriter của bạn! :) Cái này sẽ hoạt động trên Lisa (với trình biên dịch C).

Nó tính toán pitrong máy in bằng cách tính tổng độ dài của các đoạn đường gần đúng với chuỗi đường cong Bezier xấp xỉ một nửa vòng tròn, chia cho đường kính, lần 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");
}

PostScript Ungolfed Cấp 1 (tương thích 1985):

%!
/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

Đầu ra:

ps_pi


Tôi cho rằng tôi cũng cần phải tạo một phông chữ.
luser droog

Hừm. Không bao giờ có đủ chữ số theo cách này. PS chỉ có phao 32 bit.
luser droog

ý tưởng tuyệt vời, tôi thích postcript cho chơi golf.
hildred

Tôi có một phông chữ bitmap cho các chữ số nhưng chơi golf sẽ làm hỏng nó!
luser droog

2

Java, 1574 2643 1934 ký tự

1934 ký tự nén :

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

Mở rộng 2643 ký tự:

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

Phương pháp Pi được thu thập từ: /programming/8343977/calculate-pi-on-an-android-phone?rq=1


Có vẻ như bạn đã sử dụng hằng số thay vì tính PI.
hildred

Đó là một twist tốt đẹp. Làm việc trên nó bây giờ.
Clayton

Bạn có thể nén nó hơn một chút bằng cách thêm throws Exceptionvào mainvà loại bỏ các khối try-catch. Hơn nữa, bạn có thể đổi tên pisqrtcác phương pháp và loc, args, SCALE, x0x1biến tới 1 định danh char. Và bằng cách bạn phải thêm lớp hoàn chỉnh, điều này bao gồm class Foo{khai báo và nhập khẩu.
Victor Stafusa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.