pembatasan bodoh dan gurun

18

Jadi, Anda duduk di meja Anda, bermain golf program untuk menghitung 20 digit pertama pi, dan kemudian datang bos Anda dan melempar apel Anda ke luar jendela. Anda sekarang sedang mengerjakan proyek baru dan komputer ini belum memiliki kemampuan teks apa pun. Tidak ada Tanpa font. Tidak ada.

Sekarang mari kita selesaikan program itu. Hitung dan Tampilkan 20 karakter pertama pi tanpa menggunakan font apa pun yang bukan bagian dari program Anda. Output Anda dapat ditampilkan atau ditulis ke standar sebagai file gambar (jpeg, png, gif, svg (selama Anda tidak menggunakan karakter apa pun), bmp, xpm). Anda dapat menggunakan bahasa apa pun, tetapi Anda tidak dapat menggunakan fungsi font bahasa Anda, tampilan teks atau yang serupa.

bonus kecil (10 karakter) Jika itu akan berfungsi pada Lisa.

Sunting: bagi mereka yang tidak tahu inspirasi saya adalah mac pertama, dan judulnya adalah permainan kata-kata. Sebuah pujian besar untuk @Sukminder yang gif animasi-nya keren. Kontes belum berakhir jika jawaban yang lebih baik datang.

Hildred
sumber
Saya suka tantangannya, tetapi secara teknis bukankah sistem seperti itu juga tidak mampu menampilkan kode sumber? Kecuali Piet, tentu saja.
ApproachingDarknessFish
2
@ValekHalfHeart Anda dapat memuat kode sumber dari mesin yang berbeda
John Dvorak
1
Dan bagaimana Anda mendefinisikan manusia dapat dibaca? Sebagai contoh, tulisan tangan saya dapat dibaca oleh beberapa manusia (setidaknya satu) dan tidak untuk orang lain. (Omong-omong, 2 ^ (2x2) = 16, cukup mesin terbang untuk semua 11 digit;))
Kendall Frey
4
Saya tidak mengerti judul sama sekali, saya tidak mengerti bagaimana seni ASCII bisa baik-baik saja ketika kita tidak dapat menggunakan tampilan teks, dan pertanyaannya sangat membutuhkan definisi "menghitung PI".
Peter Taylor
2
Apa arti "menghitung pi"? Bisakah saya membuat kode bitmap dari 20 desimal pertama? (Tidak memanfaatkan PI built-in konstan atau serupa)
FireFly

Jawaban:

6

Python, 222 karakter

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)

Baris pertama menghitung digit pi menggunakan aproksimasi pi-3 ~= 277991633/1963319607. Tiga baris berikutnya menghasilkan 20 karakter pi menggunakan seni ASCII Nemeth Braille.

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

Saya mendorong batas-batas dalam dua arah di sini, baik dalam pengertian "menghitung Pi" dan "dapat dibaca manusia".

Keith Randall
sumber
3
Apa apaan? Saya pikir kita tidak seharusnya menggunakan output teks apa pun. Bagaimana komputer Anda akan merender *ruang dan tanpa font?
stan
@ boothby: Ini seni ASCII. Anggap *sebagai piksel hitam 1x1 dan `` sebagai piksel putih 1x1.
Keith Randall
1
Dia ada benarnya. Anda tidak dapat membuat *tanpa menggunakan font, saya pikir Anda didiskualifikasi
Sirens
18

Python, 217 byte

Membutuhkan Perpustakaan Pencitraan 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()

Hitungan byte mengasumsikan bahwa karakter yang lolos \177diganti dengan padanan literalnya (char 127 ).

Output akan muncul sebagai berikut (ini akan terbuka di viewer * .bmp default Anda):

Perhatikan bahwa ini dapat dengan mudah diparameterisasi untuk mencetak sejumlah digit yang Anda suka. Berikut ini akan menerima input integer dari stdin, dan menampilkan banyak digit:

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

Output untuk n = 80 :


Perhitungan Pi

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

Yup, itu dia. Rumus yang digunakan adalah hasil dari penerapan Transform Euler ke Seri Leibniz , dan kemudian menghitung setiap istilah dari sisa jumlah. Rumus bertemu secara linear; setiap digit membutuhkan log 2 (10) ≈ 3.32 iterasi. Bagi yang tertarik dengan derivasi, lihat Lampiran A.

Tampilan

PIL digunakan untuk pembuatan gambar, karena ini adalah perpustakaan paling nyaman yang saya tahu. Sebuah bitmap kosong 141 × 11 hitam dan putih dibuat, dan kemudian garis-garis putih digambar di atasnya dalam mode tujuh segmen, satu piksel pada satu waktu. Posisi yang diperlukan untuk menggambar setiap segmen disimpan dalam string bitmask, dengan bit yang sesuai dengan posisi berikut:

 000
3   5
3   5
 111
4   6
4   6
 222

Bit ajaib (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)menghasilkan masing-masing piksel dalam urutan berikut (basis-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

Lampiran A

Euler's Transform adalah teknik percepatan konvergensi yang berfungsi untuk semua seri yang menampilkan konvergensi monoton absolut. Seri yang dihasilkan akan konvergen secara linier, biasanya pada laju satu bit per term (perhatikan bahwa jika seri asli sudah super linier, seri yang dihasilkan akan konvergen lebih lambat). The deskripsi murni matematika agak sulit untuk diikuti, jadi saya akan mengambil pendekatan prosedural.

Kami akan mulai dengan Seri Leibniz:

Kemudian pisahkan setiap istilah menjadi dua, menggabungkan istilah tetangga:

Sederhana:

Generalisasi:

Perhatikan bahwa ½ pemimpin tidak memiliki istilah mitra, dan dengan demikian dikeluarkan dari sisa jumlah. Ini adalah istilah pertama dari seri yang diubah. Untuk menemukan istilah berikutnya, kami ulangi prosesnya lagi:

Dan lagi:

Dan lagi:

Dan sekali lagi untuk ukuran yang baik:

Pada titik ini kita memiliki lima istilah pertama, dan istilah keenam sudah jelas. Ini sudah cukup untuk digeneralisasi, jadi kita akan berhenti di sini. Kami akan mulai dengan memperhitungkan pembilang dan penyebut:

Penyebut jelas mengandung dua faktorial dari 2n + 1 , jadi kita akan menambal bahwa dalam:

Semuanya cocok, kecuali untuk dua istilah pertama yang memiliki 2 untuk penghitungan yang tidak terhitung dalam penyebut. Kami dapat memperbaikinya dengan mengalikan seluruh ekspresi dengan 2 :

2 3 = 2 · 4 , jadi:

Pembilang sekarang dapat dengan mudah diidentifikasi sebagai n!.

Perhatikan bahwa faktor yang ditambahkan ke setiap istilah berturut-turut, n / (2n +1) , mendekati ½ saat n menjadi besar, menyiratkan konvergensi linier pada laju satu bit per istilah - ini sebenarnya berdasarkan desain. Hasil yang bagus, tetapi akan lebih baik tanpa faktorial di sana. Apa yang dapat kita lakukan di sini adalah mempertimbangkan setiap istilah yang berurutan dari sisa jumlah, yang akan menghasilkan ekspresi bersarang:



Ini dapat ditulis ulang sebagai relasi berulang:

Di mana n dihitung mundur dari ⌈ log 2 (10) · d ⌉ .. 0 , di mana d adalah jumlah digit yang diperlukan.

Mungkin menarik untuk dicatat bahwa titik stabil dari perulangan ini adalah tepat 2 (atau 4 jika Anda telah menggandakannya, seperti yang saya miliki dalam penerapan di atas), sehingga Anda dapat menyimpan sejumlah iterasi dengan menginisialisasi dengan benar. Padahal, menginisialisasi ke nilai acak yang Anda butuhkan di tempat lain, dan melemparkan beberapa iterasi tambahan di atas umumnya lebih murah byte-bijaksana.

primo
sumber
1
Bagus sekali, terima kasih untuk pelajarannya! Apa yang tidak saya dapatkan adalah apa yang dilakukan pdi dalam p/2 * x/p + ..... AIUI Python mendukung promosi otomatis ke datatype biginteger-ish, jadi itu seharusnya bukan hal yang presisi, tapi entah bagaimana pitu penting dan jangan membatalkan seperti yang saya bayangkan mereka untuk ... apa yang saya lewatkan di sini?
FireFly
@ FireFly pdiinisialisasi aneh, sehingga p/2/psetara - di bawah pembagian integer - ke ((p-1)/2)/p. Ini menghasilkan 1/3, 2/5, 3/7, dll istilah yang berasal di atas.
Primo
12

#C - 777 Karakter

C - 731 Karakter

Mencetak GIF ke stdout.

  • Quirk: Tidak ada koma setelah dulu 3.

Menjahit bersama GIF dari tajuk yang sudah dikonfigurasi sebelumnya + setiap digit diwakili oleh font buatan rumah (tertanam) berukuran 5x5 piksel.

Hasil

masukkan deskripsi gambar di sini

Itu ada di sana --- ^

Perhatikan bahwa GIF menghilang, terkadang, di Chrome setelah satu kali proses.

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

Pengantar singkat:

Perhitungan PI

Pi dihitung menggunakan versi Dik Winter yang sedikit dimodifikasi dan implementasi Achim Flammenkamp dari Rabinowitz dan algoritma Wagon untuk menghitung angka π.

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

Generasi GIF

Gambar GIF memiliki canvasproperti di header. Kita dapat menggunakan ini dalam kombinasi dengan menampilkan beberapa gambar dengan mengatur leftproperti untuk setiap digit yang sesuai - di mana setiap digit adalah gambar (tertanam) dalam dirinya sendiri.

Dokumentasi.

Contoh:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

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

Kode diperluas (dengan banyak komentar)

Berantakan, tetapi itu adalah bagian dari minimalisasi :

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

Mencari untuk menggunakan algoritma yang lebih pendek / lainnya untuk menghitung π.

Runium
sumber
2
Saya tidak melihat titik setelah 3 pertama dalam gambar.
Victor Stafusa
1
Apakah Anda memiliki tautan ke info tentang algoritma pembuatan desimal pi? Saya bermain-main dengan kode Anda sedikit (setelah melepaskan barang-barang GIF), tapi saya tidak benar-benar melihat mengapa itu menghasilkan angka pi ...
FireFly
7

JavaScript, 680 karakter

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

Ini dapat dilihat di browser web; angka-angka tersebut dikeluarkan sebagai jalur SVG.

Cuplikan layar dari output SVG di browser web

  • Itu tidak menghitung pi dengan cara yang menarik, dan JS tidak memiliki tipe angka dengan presisi untuk menampilkan 20 digit.

  • Untuk menyimpan karakter, saya menghapus data jalur untuk "0", karena tidak muncul dalam urutan.

JustinMimbs
sumber
Ooh, pendekatan berbasis vektor. Sangat bagus, pekerjaan yang baik pada font juga.
FireFly
5

Java - 866 860 857 853 karakter, ditambah versi curang dengan 574 karakter

Menggunakan rumus Simon Plouffe dari tahun 1996, menghasilkan x.pngfile dengan angka seperti jam digital putih di latar belakang hitam:

pi

Ini adalah kode terkompresi:

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

Itu, dengan mengidentifikasi dan beberapa spasi putih akan menjadi ini:

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

Menyontek aturan dan mempertimbangkan bahwa perhitungan PI dapat dilakukan sebagai "representasi numerik dari String 3.1415926535897934384", ini dapat dikurangi menjadi 574 karakter:

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);}}
Victor Stafusa
sumber
4

Java - 642 622 karakter

Menyalin dari jawaban saya sebelumnya, menggunakan rumus Simon Plouffe dari tahun 1996. Tetapi menghasilkan ASCII-art sebagai gantinya:

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

Semua itu, dengan beberapa identifikasi dan spasi, dan sedikit bantuan bagi pembaca untuk memahami arti angka ajaib:

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

Keluaran:

###         #  # #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  # #  
  #         #  # #    #  #    # #    #  #    #      #  #    # #  # #    #  # #    #    #    #  # #  # #  
###         #  ###    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###  ###  
  #         #    #    #    #    #  #    # #    #    #    #  # #    #    #    #    #  #      #  # #    #  
###   #     #    #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###    # 
Victor Stafusa
sumber
4

C, 253 250 karakter

Kira-kira pi menggunakan algoritma dalam kode @ Sukminder (sedikit meminjam dan refactoring kode mereka sedikit demi sedikit). Keluaran gambar biner PBM , yang kemudian dapat mis dikonversi dengan 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);}

Seperti apa hasilnya dengan renderer PPM berbasis Braille saya:

Tangkapan layar output

Memiliki kekhasan yang sama dengan jawaban @ Sukminder karena tidak memiliki pemisah desimal. Selain itu, output tambang adalah vertikal, dan apakah itu dapat dibaca manusia dapat diperdebatkan ...

Edit: diterapkan saran @ ugoren.

FireFly
sumber
Perbaikan kecil: beralih putske for inisialisasi, menentukan L[5]dan menghilangkan ,0. Buat dparameter untuk main(simpan koma).
ugoren
4

PHP 380

membutuhkan gd diaktifkan untuk output gambar

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

masukkan deskripsi gambar di sini

perhitungan pi: karena basis php memiliki presisi default 14 dan saya tidak ingin mengkompilasi ulang server dengan ekstensi presisi acak diaktifkan, saya bahkan tidak bisa mendekati PI dengan desimal yang diperlukan, jadi alih-alih menghitung tau / 2 lalu sisa desimal

karena grafik terbuat dari 0 dan 1, saya dapat mencoba menggunakan WBMP sebagai format nanti untuk melihat apakah saya dapat menghapus gd

Einacio
sumber
gambar itu merah di atas hitam, dan sangat kecil, tetapi pada 500% Anda dapat membacanya jika Anda melihat dari dekat. (dan tidak buta warna.)
Hildred
@dibuat setiap karakter 3x5 with 1 px between chars. warnanya merah hanya untuk mengurangi 4 karakter, tetapi mengingat bahwa saya tidak akan menang, saya akan mengubahnya menjadi putih agar mudah dibaca
Einacio
Komentar saya tidak dimaksudkan sebagai kritik, tetapi sebagai penjelasan, untuk mendorong suara.
Hildred
Apakah imagecreateindex menyimpan karakter? apakah fungsi seperti itu ada?
Hildred
@hildred ketika bekerja dengan gambar pallete ( imagecreate), doa pertama dari imagecolorallocateset warna latar belakang, dan yang kedua diperlukan untuk mengatur warna tulisan. jadi berakhir lebih lama
Einacio
4

Printer C + LaserWriter 599 - 10 = 589

Pipa output ke LaserWriter Anda! :) Ini seharusnya bekerja pada Lisa (dengan kompiler C).

Ini menghitung pidalam printer dengan menghitung jumlah panjang segmen garis yang mendekati urutan kurva Bezier yang kira-kira setengah lingkaran, dibagi dengan diameter, kali 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 Level-1 (kompatibel 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

Keluaran:

ps_pi

luser droog
sumber
Saya kira saya perlu membuat font juga.
luser droog
Hmm. Tidak akan pernah mendapatkan angka yang cukup dengan cara ini. PS hanya memiliki float 32-bit.
luser droog
ide keren, saya suka postscript untuk bermain golf.
Hildred
Saya memang memiliki font bitmap untuk digit-digit itu, tetapi golf hanya akan merusaknya!
luser droog
2

Java, 1574 2643 1934 karakter

Dikompresi 1934 karakter:

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

Diperluas 2643 karakter:

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

Metode pi dikumpulkan dari: /programming/8343977/calculate-pi-on-an-android-phone?rq=1

Clayton
sumber
Sepertinya Anda menggunakan konstanta alih-alih menghitung PI.
Hildred
Itu adalah twist yang bagus. Sedang mengerjakannya sekarang.
Clayton
Anda mungkin kompres sedikit lebih dengan menambahkan throws Exceptiondalam maindan menghapus blok try-catch. Selanjutnya, Anda dapat mengubah nama pidan sqrtmetode dan loc, args, SCALE, x0dan x1variabel untuk 1 pengidentifikasi arang. Dan omong-omong Anda harus menambahkan kelas lengkap, ini termasuk class Foo{deklarasi dan impor.
Victor Stafusa