stupide restrizioni e deserto


18

Quindi, eri seduto alla tua scrivania, giocando a golf un programma per calcolare le prime 20 cifre di pi, e poi arriva il tuo capo e lancia la tua mela fuori dalla finestra. Ora stai lavorando a un nuovo progetto e questo computer non ha ancora alcuna capacità di testo. Nessuna. Nessun carattere. Niente.

Ora finiamo quel programma. Calcola e visualizza i primi 20 caratteri di pi senza usare caratteri che non fanno parte del tuo programma. L'output può essere visualizzato o scritto come standard come file di immagine (jpeg, png, gif, svg (purché non si utilizzino caratteri), bmp, xpm). È possibile utilizzare qualsiasi lingua, ma non è possibile utilizzare le funzioni dei caratteri della lingua, la visualizzazione del testo o simili.

piccolo bonus (10 caratteri) Se funzionerà su una Lisa.

Modifica: per coloro che non l'hanno capito, la mia ispirazione è stata il primo mac, e il titolo è un gioco di parole. Un grande complimento a @Sukminder la cui gif animata è semplicemente fantastica. Il concorso non finisce se arriva una risposta migliore.


Mi piace la sfida, ma tecnicamente un tale sistema non sarebbe in grado di visualizzare il codice sorgente? Ad eccezione di Piet, ovviamente.
Approaching

2
@ValekHalfHeart puoi caricare il codice sorgente da un'altra macchina
John Dvorak,

1
E come si definisce la lettura umana? Ad esempio, la mia calligrafia è leggibile da alcuni umani (almeno uno) e non da altri. (A proposito, 2 ^ (2x2) = 16, glifi sufficienti per tutte e 11 le cifre.;))
Kendall Frey,

4
Non capisco affatto il titolo, non capisco come l'arte ASCII possa essere ok quando non possiamo usare la visualizzazione del testo, e la domanda ha davvero bisogno di una definizione di "calcola PI".
Peter Taylor,

2
Cosa significa veramente "calcola pi"? Potrei codificare un bitmap dei primi 20 decimali? (Non utilizza alcuna costante PI integrata o simile)
FireFly

Risposte:


6

Python, 222 caratteri

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)

La prima riga calcola le cifre di pi usando l'approssimazione pi-3 ~= 277991633/1963319607. Le tre righe successive generano 20 caratteri di pi usando l'arte ASCII di Nemeth Braille.

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

Sto spingendo i confini in due direzioni qui, sia in senso "calcolando Pi" che "leggibile dall'uomo".


3
Che diamine? Pensavo che non avremmo dovuto usare alcun output di testo. In che modo il tuo computer renderà gli *spazi e gli spazi senza un carattere?
stand dal

@boothby: è arte ASCII. Pensa *a un pixel nero 1x1 e `` a un pixel bianco 1x1.
Keith Randall,

1
Ha un punto. Non puoi renderizzare a *senza usare i caratteri, penso che tu sia squalificato
Sirene

18

Python, 217 byte

Richiede la libreria di imaging 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()

Il conteggio dei byte presuppone che il carattere di escape \177sia sostituito con il suo equivalente letterale (char 127 ).

L'output apparirà come segue (si aprirà nel tuo visualizzatore * .bmp predefinito):

Si noti che questo potrebbe essere facilmente parametrizzato per stampare qualsiasi numero di cifre che ti piace. Quanto segue accetterà un input intero da stdin e visualizzerà quel numero di cifre:

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

Uscita per n = 80 :


Calcolo Pi

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

Sì, tutto qui. La formula utilizzata è il risultato dell'applicazione della trasformazione di Euler alla serie Leibniz e quindi della fattorizzazione di ogni termine dal resto della somma. La formula converge linearmente; ogni cifra richiede il registro 2 (10) ≈ 3,32 iterazioni. Per coloro che sono interessati alla derivazione, vedere l'Appendice A.

Schermo

PIL è utilizzato per la generazione di immagini, perché è la libreria più comoda che io conosca. Viene creata una bitmap in bianco e nero 141 × 11 , quindi vengono disegnate linee bianche su di esso in un modo a sette segmenti, un pixel alla volta. Le posizioni richieste per disegnare ogni segmento sono memorizzate in una stringa maschera di bit, con bit corrispondenti alle seguenti posizioni:

 000
3   5
3   5
 111
4   6
4   6
 222

Il bit di magia (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)produce ciascun pixel nel seguente ordine (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

Appendice A

La trasformazione di Euler è una tecnica di accelerazione della convergenza che funziona per qualsiasi serie che mostra una convergenza monotonica assoluta. Le serie risultanti convergeranno linearmente, in genere alla velocità di un bit per termine (si noti che se la serie originale era già super-lineare, le serie risultanti convergeranno effettivamente più lentamente). La descrizione puramente matematica è un po 'difficile da seguire, quindi prenderò un approccio procedurale.

Inizieremo con la serie Leibniz:

Quindi dividi ogni termine a metà, combinando i termini vicini:

semplificata:

generalizzato:

Si noti che il primo ½ non aveva un termine per il partner e quindi è stato escluso dal resto della somma. Questo è il primo termine della serie trasformata. Per trovare il termine successivo, ripetiamo nuovamente il processo:

E di nuovo:

E di nuovo:

E ancora una volta per buona misura:

A questo punto abbiamo i primi cinque termini e il sesto termine è evidente. Questo dovrebbe essere sufficiente per generalizzare, quindi ci fermeremo qui. Inizieremo prendendo in considerazione i numeratori e i denominatori:

I denominatori evidentemente contengono un doppio fattoriale di 2n + 1 , quindi lo correggeremo in:

Tutto si adatta, tranne i primi due termini che hanno un non contabilizzato per 2 nel denominatore. Possiamo risolverlo moltiplicando l'intera espressione per 2 :

2 3 = 2 · 4 , quindi:

Il numeratore ora può essere facilmente identificato come n! .

Si noti che il fattore aggiunto a ciascun termine successivo, n / (2n + 1) , si avvicina a ½ man mano che n diventa grande, implicando una convergenza lineare al ritmo di un bit per termine - questo è in effetti in base alla progettazione. Un bel risultato, ma sarebbe ancora più bello senza i fattoriali lì dentro. Quello che possiamo fare qui è di fattorizzare ogni termine successivo dal resto della somma, che genererà un'espressione nidificata:



Questo può essere riscritto come relazione di ricorrenza:

Dove n conta indietro da ⌈ log 2 (10) · d ⌉ .. 0 , dove d è il numero di cifre richieste.

Potrebbe essere interessante notare che il punto stabile di questa ricorrenza è esattamente 2 (o 4 se l'hai raddoppiato, come ho fatto nell'impianto sopra), quindi puoi salvare un numero di iterazioni inizializzando correttamente. Tuttavia, inizializzare su un valore casuale che è necessario altrove e lanciare alcune iterazioni extra in alto è generalmente più economico in termini di byte.


1
Molto bello, grazie per la lezione! Quello che non capisco è che cosa la pa p/2 * x/p + ...sta facendo .. AIUI Python supporta la promozione automatica di un tipo di dati BigInteger-ish, quindi non dovrebbe essere una cosa di precisione, ma in qualche modo quelli ps la materia e non annullano come immagino loro a ... cosa mi sto perdendo qui?
FireFly

@FireFly pinizializzato dispari, quindi p/2/pè equivalente - sotto divisione intera - a ((p-1)/2)/p. Questo produce il 1/3, 2/5, 3/7, termini ecc derivato sopra.
primo

12

#C - 777 Personaggi

C - 731 personaggi

Stampa GIF su stdout .

  • Quirk: nessuna virgola dopo la prima 3 .

Ricucendo GIF dall'intestazione preconfigurata + ogni cifra rappresentata da un font (incorporato) preparato in casa di 5x5 pixel.

Risultato

inserisci qui la descrizione dell'immagine

È lì --- ^

Si noti che GIF svanisce, a volte, in Chrome dopo una corsa.

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

Breve introduzione:

Calcolo di PI

Il Pi viene calcolato usando una versione leggermente modificata di Dik Winter e l'implementazione di Achin Flammenkamp dell'algoritmo di Rabinowitz e Wagon per calcolare cifre di π.

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

Generazione GIF

Le immagini GIF hanno una canvasproprietà nell'intestazione. Possiamo usarlo in combinazione con la visualizzazione di più immagini impostando la leftproprietà per ogni cifra di conseguenza - dove ogni cifra è un'immagine (incorporata) in sé.

Documentazione.

Esempio:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

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

Codice espanso (con un sacco di commenti)

Disordinato, ma fa parte della minimizzazione :

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

Cercando di usare un algoritmo più breve / altro per calcolare π.


2
Non vedo il punto dopo i primi 3 nell'immagine.
Victor Stafusa,

1
Hai un link alle informazioni sull'algoritmo di generazione dei decimali pi? Ho giocato un po 'con il tuo codice (dopo aver eliminato le cose GIF), ma non vedo davvero perché si traduca in cifre di pi ...
FireFly

7

JavaScript, 680 caratteri

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

Questo può essere visualizzato in un browser Web; i numeri vengono emessi come percorsi SVG.

Schermata dell'output SVG in un browser Web

  • Non calcola pi in modo interessante e JS non ha un tipo di numero con precisione per visualizzare 20 cifre.

  • Per salvare i caratteri, ho omesso i dati del percorso per "0", poiché non vengono visualizzati nella sequenza.


Ooh, un approccio basato sul vettore. Molto bello, ottimo lavoro anche sul font.
FireFly,

5

Java - 866 860 857 853 caratteri, oltre a una versione cheat con 574 caratteri

Utilizzando la formula Simon Plouffe del 1996, genera un x.pngfile con numeri bianchi simili a un orologio digitale su uno sfondo nero:

pi

Questo è il codice compresso:

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

Che, con l'identificazione e alcuni spazi bianchi sarebbe questo:

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

Truffando le regole e considerando che il calcolo di PI può essere fatto come "rappresentazione numerica della stringa 3.1415926535897934384", questo può essere ridotto a 574 caratteri:

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 caratteri

Copia dalla mia risposta precedente, usando la formula di Simon Plouffe del 1996. Ma invece genera ASCII-art:

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

Tutto ciò, con alcune identificazioni e spazi, e un po 'di aiuto al lettore per capire il significato dei numeri magici:

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

Produzione:

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

4

C, 253 250 caratteri

Approssima il pi usando l'algoritmo nel codice di @ Sukminder (prendendo spudoratamente in prestito e refactoring il loro codice un po '). Emette un'immagine PBM binaria , che potrebbe ad esempio essere convertita con 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);}

Ecco come appare l'output con il mio renderer PPM basato su Braille:

Schermata dell'output

Ha la stessa stranezza della risposta di @ Sukminder in quanto manca un separatore decimale. Inoltre, l'output del mio è verticale e se è leggibile dall'uomo è discutibile ...

Modifica: applicati i suggerimenti di @ugoren.


Piccoli miglioramenti: mossa putsin for inizializzazione, definiscono L[5]e omettere ,0. Crea dun parametro per main(salva una virgola).
ugoren,

4

PHP 380

richiede gd abilitato per l'output delle immagini

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

inserisci qui la descrizione dell'immagine

calcolo pi: dal momento che php di base ha una precisione predefinita di 14 e non volevo ricompilare il server con le estensioni di precisione arbitrarie abilitate, non potevo nemmeno approssimare PI con i decimali richiesti, quindi calcola tau / 2 e quindi il resto dei decimali

dato che la grafica è composta da 0 e 1, potrei provare a usare WBMP come formato in seguito per vedere se posso rimuovere gd


quell'immagine è rossa su nero e molto piccola, ma al 500% puoi leggerla se guardi da vicino. (e non sono daltonici.)
hildred il

@hildred ogni personaggio è 3x5 with 1 px between chars. il colore è rosso solo per ridurre 4 caratteri, ma considerando che non
vincerò

Il mio commento non era inteso come una critica, ma come una spiegazione, per incoraggiare i voti.
Hildred

Imagecreateindex salverà qualche personaggio? esiste una tale funzione?
Hildred

@hildred quando si lavora con un'immagine pallete ( imagecreate), la prima invocazione di imagecolorallocateimposta il colore di sfondo e una seconda è necessaria per impostare il colore di scrittura. quindi finisce più a lungo
Einacio,

4

Stampante C + LaserWriter 599 - 10 = 589

Installa l'output sul tuo LaserWriter! :) Questo dovrebbe funzionare su una Lisa (con un compilatore C).

Calcola pinella stampante calcolando la somma delle lunghezze dei segmenti di linea che si avvicinano a una sequenza di curve di Bezier che si avvicina a un semicerchio, diviso per diametro, volte 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 (compatibile 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

Produzione:

ps_pi


Suppongo che anche io debba creare un font.
Luser droog

Hmm. Non avrò mai abbastanza cifre in questo modo. PS ha solo float a 32 bit.
Luser droog

bella idea, mi piace Postscript per il golf.
Hildred

Ho un carattere bitmap per le cifre, ma il golf lo rovinerà!
droog dell'utente

2

Java, 1574 2643 1934 caratteri

1934 caratteri compressi :

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

Expanded 2643 caratteri:

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

Metodo Pi raccolto da: /programming/8343977/calculate-pi-on-an-android-phone?rq=1


Sembra che tu abbia usato una costante invece di calcolare PI.
Hildred

Questa è una bella svolta. Ci sto lavorando adesso.
Clayton,

Si può comprimere un po 'più con l'aggiunta throws Exceptionin maine la rimozione del blocco try-catch. Inoltre, è possibile rinominare pie sqrtmetodi e le loc, args, SCALE, x0e x1le variabili a 1 identificatori char. E tra l'altro è necessario aggiungere la classe completa, questo include la class Foo{dichiarazione e le importazioni.
Victor Stafusa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.