restrictions stupides et désert

18

Donc, vous étiez assis à votre bureau, jouant à un programme pour calculer les 20 premiers chiffres de pi, et votre patron arrive et jette votre pomme IIe par la fenêtre. Vous travaillez maintenant sur un nouveau projet et cet ordinateur n'a pas encore de capacité de texte. Aucun. Pas de polices. Rien.

Maintenant, terminons ce programme. Calculez et affichez les 20 premiers caractères de pi sans utiliser de polices qui ne font pas partie de votre programme. Votre sortie peut être affichée ou écrite en sortie standard sous forme de fichier image (jpeg, png, gif, svg (tant que vous n'utilisez aucun caractère), bmp, xpm). Vous pouvez utiliser n'importe quelle langue, mais vous ne pouvez pas utiliser les fonctions de police, l'affichage de texte ou similaire de votre langue.

petit bonus (10 caractères) Si cela fonctionnera sur une Lisa.

Edit: pour ceux qui ne l'ont pas compris, mon inspiration était le premier mac, et le titre est un jeu de mots. Un grand bravo à @Sukminder dont le gif animé est juste cool. Le concours n'est pas terminé si une meilleure réponse arrive.

hildred
la source
J'aime le défi, mais techniquement, un tel système ne serait-il pas également incapable d'afficher le code source? Sauf pour Piet, bien sûr.
ApproachingDarknessFish
2
@ValekHalfHeart, vous pouvez charger le code source à partir d'une autre machine
John Dvorak
1
Et comment définissez-vous lisible par l'homme? Par exemple, mon écriture est lisible pour certains humains (au moins un) et pas pour d'autres. (Au fait, 2 ^ (2x2) = 16, assez de glyphes pour les 11 chiffres.;))
Kendall Frey
4
Je ne comprends pas du tout le titre, je ne comprends pas comment l'art ASCII peut être correct quand nous ne pouvons pas utiliser l'affichage de texte, et la question a vraiment besoin d'une définition de "calculer PI".
Peter Taylor
2
Que signifie vraiment "calculer pi"? Puis-je coder en dur une image bitmap des 20 premières décimales? (N'utilise pas de constante PI intégrée ou similaire)
FireFly

Réponses:

6

Python, 222 caractères

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 première ligne calcule les chiffres de pi en utilisant l'approximation pi-3 ~= 277991633/1963319607. Les trois lignes suivantes produisent 20 caractères de pi en utilisant l'art ASCII Nemeth Braille.

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

Je repousse les limites dans deux directions ici, à la fois dans les sens "calculant Pi" et "lisible par l'homme".

Keith Randall
la source
3
Que diable? Je pensais que nous n'étions pas censés utiliser de sortie de texte. Comment votre ordinateur va-t-il rendre les *espaces et les espaces sans police?
boothby
@boothby: C'est de l'art ASCII. Considérez-le *comme un pixel noir 1x1 et `` comme un pixel blanc 1x1.
Keith Randall
1
Il a raison. Vous ne pouvez pas rendre un *sans utiliser de polices, je pense que vous êtes disqualifié
Sirens
18

Python, 217 octets

Nécessite la bibliothèque d'imagerie 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()

Le nombre d'octets suppose que le caractère échappé \177est remplacé par son équivalent littéral (caractère 127 ).

La sortie apparaîtra comme suit (elle s'ouvrira dans votre visionneuse * .bmp par défaut):

Notez que cela pourrait facilement être paramétré pour imprimer autant de chiffres que vous le souhaitez. Ce qui suit acceptera une entrée entière de stdin et affichera autant de chiffres:

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

Sortie pour n = 80 :


Calcul Pi

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

Ouais, c'est tout. La formule utilisée est le résultat de l'application de la transformation d' Euler à la série Leibniz , puis de la factorisation de chaque terme du reste de la somme. La formule converge linéairement; chaque chiffre nécessite log 2 (10) ≈ 3,32 itérations. Pour ceux qui s'intéressent à la dérivation, voir l'annexe A.

Afficher

PIL est utilisé pour la génération d'images, car c'est la bibliothèque la plus pratique que je connaisse. Une image bitmap noir et blanc 141 × 11 vierge est créée, puis des lignes blanches sont dessinées dessus en sept segments, un pixel à la fois. Les positions requises pour dessiner chaque segment sont stockées dans une chaîne de masque de bits, avec des bits correspondant aux positions suivantes:

 000
3   5
3   5
 111
4   6
4   6
 222

Le peu de magie (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)produit chaque pixel dans l'ordre suivant (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

Annexe A

La transformation d'Euler est une technique d'accélération de convergence qui fonctionne pour n'importe quelle série qui affiche une convergence monotone absolue. La série résultante convergera linéairement, généralement à la vitesse d'un bit par terme (notez que si la série d'origine était déjà super-linéaire, la série résultante convergera en fait plus lentement). La description purement mathématique est un peu difficile à suivre, je vais donc adopter une approche procédurale.

Commençons par la série Leibniz:

Divisez ensuite chaque terme en deux en combinant les termes voisins:

Simplifié:

Généralisé:

Notez que le premier ½ n'avait pas de terme partenaire et était donc exclu du reste de la somme. Il s'agit du premier terme de la série transformée. Pour trouver le terme suivant, nous répétons le processus à nouveau:

Et encore:

Et encore:

Et encore une fois pour faire bonne mesure:

À ce stade, nous avons les cinq premiers termes, et le sixième terme est évident. Cela devrait être suffisant pour généraliser, alors nous nous arrêterons ici. Nous commencerons par factoriser les numérateurs et les dénominateurs:

Les dénominateurs contiennent évidemment un double factoriel de 2n + 1 , nous allons donc corriger cela dans:

Tout va bien, sauf pour les deux premiers termes qui ont un inexpliqué pour 2 dans le dénominateur. Nous pouvons résoudre ce problème en multipliant l'expression entière par 2 :

2 3 = 2 · 4 , donc:

Le numérateur peut maintenant être facilement identifié comme n! .

Notez que le facteur ajouté à chaque terme successif, n / (2n + 1) , approche ½ lorsque n devient grand, ce qui implique une convergence linéaire au rythme d'un bit par terme - c'est en fait par conception. Un bon résultat, mais ce serait encore plus agréable sans les factoriels. Ce que nous pouvons faire ici est de factoriser chaque terme successif du reste de la somme, ce qui générera une expression imbriquée:



Cela peut être réécrit comme une relation de récurrence:

n compte à rebours à partir de ⌈ log 2 (10) · d ⌉ .. 0 , où d est le nombre de chiffres requis.

Il peut être intéressant de noter que le point stable de cette récurrence est exactement 2 (ou 4 si vous l'avez doublé, comme je l'ai fait dans l'implémentation ci-dessus), vous pouvez donc enregistrer un certain nombre d'itérations en l'initialisant correctement. Cependant, initialiser à une valeur aléatoire dont vous avez besoin ailleurs, et lancer quelques itérations supplémentaires sur le dessus est généralement moins cher en octets.

primo
la source
1
Très bien, merci pour la leçon! Ce que je ne comprends pas, c'est ce que fait pin p/2 * x/p + .... AIUI Python prend en charge la promotion automatique vers un type de données de grande taille, donc cela ne devrait pas être une chose de précision, mais d'une manière ou d'une autre, ces pquestions sont importantes et ne s'annulent pas comme j'imagine eux à ... que me manque-t-il ici?
FireFly
@FireFly pinitialisé impair, ce qui p/2/péquivaut - sous division entière - à ((p-1)/2)/p. Cela produit le 1/3, 2/5, 3/7, etc. termes dérivés ci - dessus.
primo
12

#C - 777 caractères

C - 731 caractères

Imprime GIF sur stdout.

  • Quirk: Pas de virgule après le premier 3.

Assemblage de GIF à partir de l'en-tête préconfiguré + chaque chiffre représenté par une police (intégrée) de 5 x 5 pixels.

Résultat

entrez la description de l'image ici

C'est là --- ^

Notez que GIF disparaît, parfois, dans Chrome après une exécution.

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

Brève introduction:

Calcul de PI

Pi est calculé en utilisant une version légèrement modifiée de l'implémentation de Dik Winter et Achim Flammenkamp de l'algorithme de Rabinowitz et Wagon pour calculer les chiffres de π.

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

Génération GIF

Les images GIF ont une canvaspropriété dans l'en-tête. Nous pouvons l'utiliser en combinaison avec l'affichage de plusieurs images en définissant la leftpropriété pour chaque chiffre en conséquence - où chaque chiffre est une image (intégrée) en soi.

Documentation.

Exemple:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

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

Code étendu (avec beaucoup de commentaires)

Désordonné, mais cela fait partie de la minimisation :

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

Vous cherchez à utiliser un algorithme plus court / autre pour calculer π.

Runium
la source
2
Je ne vois pas le point après les 3 premiers de l'image.
Victor Stafusa
1
Avez-vous un lien vers des informations sur l'algorithme de génération de décimales pi? J'ai un peu joué avec votre code (après avoir supprimé les trucs GIF), mais je ne vois pas vraiment pourquoi cela donne des chiffres de pi ...
FireFly
7

JavaScript, 680 caractères

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

Cela peut être consulté dans un navigateur Web; les nombres sont sortis sous forme de chemins SVG.

Capture d'écran de la sortie SVG dans un navigateur Web

  • Il ne calcule pas pi de manière intéressante, et JS n'a pas de type numérique avec précision pour afficher 20 chiffres.

  • Pour enregistrer des caractères, j'ai omis les données de chemin pour "0", car elles n'apparaissent pas dans la séquence.

JustinMimbs
la source
Ooh, une approche vectorielle. Très beau travail sur la police aussi.
FireFly
5

Java - 866 860 857 853 caractères, plus une version de triche avec 574 caractères

En utilisant la formule de Simon Plouffe de 1996, génère un x.pngfichier avec des nombres blancs ressemblant à une horloge numérique sur fond noir:

pi

Voici le code compressé:

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

Cela, avec l'identification et certains espaces blancs serait le suivant:

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

En trichant les règles et en considérant que le calcul de PI peut être fait comme "la représentation numérique de la chaîne 3.1415926535897934384", cela peut être réduit à 574 caractères:

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
la source
4

Java - 642 622 caractères

Copie de ma réponse précédente, en utilisant la formule de Simon Plouffe de 1996. Mais produit de l'art ASCII à la place:

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

Tout cela, avec quelques identifiants et espaces, et un peu d'aide au lecteur pour comprendre la signification des nombres magiques:

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

Production:

###         #  # #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  # #  
  #         #  # #    #  #    # #    #  #    #      #  #    # #  # #    #  # #    #    #    #  # #  # #  
###         #  ###    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###  ###  
  #         #    #    #    #    #  #    # #    #    #    #  # #    #    #    #    #  #      #  # #    #  
###   #     #    #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###    # 
Victor Stafusa
la source
4

C, 253250 caractères

Approximation de pi en utilisant l'algorithme du code de @ Sukminder (empruntant et refactorisant sans vergogne un peu leur code) Sort une image PBM binaire , qui pourrait ensuite par exemple être convertie avec 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);}

Voici à quoi ressemble la sortie avec mon moteur de rendu PPM en braille:

Capture d'écran de la sortie

A la même bizarrerie que la réponse de @ Sukminder en ce qu'il manque un séparateur décimal. De plus, la sortie de la mienne est verticale, et si elle est lisible par l'homme est discutable ...

Edit: appliqué les suggestions de @ ugoren.

Luciole
la source
Petites améliorations: passez putsà l' for initialisation, définissez L[5]et omettez ,0. Créez dun paramètre pour main(enregistrer une virgule).
ugoren
4

PHP 380

nécessite gd activé pour la sortie d'image

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

entrez la description de l'image ici

calcul pi: étant donné que la base php a une précision par défaut de 14 et que je ne voulais pas recompiler le serveur avec les extensions de précision arbitraires activées, je ne pouvais même pas approximer PI avec les décimales requises, donc à la place il calcule tau / 2 puis le reste des décimales

puisque le graphique est fait de 0 et de 1, je peux essayer d'utiliser WBMP comme format plus tard pour voir si je peux supprimer gd

Einacio
la source
cette image est rouge sur noir, et vraiment petite, mais à 500%, vous pouvez la lire si vous regardez de près. (et ne sont pas daltoniens.)
hildred
@hildred est chaque personnage 3x5 with 1 px between chars. la couleur est rouge juste pour réduire 4 caractères, mais étant donné que je ne gagnerai pas, je vais le changer en blanc pour plus de lisibilité
Einacio
Mon commentaire n'a pas été conçu comme une critique, mais comme une explication, afin d'encourager les votes.
hildred
Imagecreateindex enregistrerait-il des caractères? existe-t-il une telle fonction?
hildred
@hildred lorsque vous travaillez avec une image de palette ( imagecreate), la première invocation de imagecolorallocatedéfinit la couleur d'arrière-plan et une seconde est nécessaire pour définir la couleur d'écriture. donc ça se termine plus longtemps
Einacio
4

Imprimante C + LaserWriter 599 - 10 = 589

Dirigez la sortie vers votre LaserWriter! :) Cela devrait fonctionner sur une Lisa (avec un compilateur C).

Il calcule pidans l'imprimante en calculant la somme des longueurs des segments de ligne qui se rapprochent d'une séquence de courbes de Bézier qui se rapproche d'un demi-cercle, divisé par le diamètre, multiplié par 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 non-niveau 1 (compatible 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

Production:

ps_pi

luser droog
la source
Je suppose que je dois aussi créer une police.
luser droog
Hmm. Ne jamais obtenir suffisamment de chiffres de cette façon. PS n'a que des flottants 32 bits.
luser droog
idée sympa, j'aime le postscript pour le golf.
hildred
J'ai une police bitmap pour les chiffres mais le golf va tout simplement le gâcher!
luser droog
2

Java, 1574 2643 1934 caractères

1934 caractères compressés :

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

Expansés 2643 caractères:

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

Méthode Pi collectée sur: /programming/8343977/calculate-pi-on-an-android-phone?rq=1

Clayton
la source
Il semble que vous ayez utilisé une constante au lieu de calculer PI.
hildred
C'est une belle tournure. J'y travaille maintenant.
Clayton
Vous pouvez compresser un peu plus en ajoutant throws Exceptiondans mainet le retrait du bloc try-catch. De plus, vous pouvez renommer piet les sqrtméthodes et les loc, args, SCALE, x0et les x1variables à 1 identificateurs char. Et au fait, vous devez ajouter la classe complète, cela inclut la class Foo{déclaration et les importations.
Victor Stafusa