глупые ограничения и пустыня

18

Итак, вы сидели за своим столом и играли в гольф, рассчитывая первые 20 цифр числа Пи, а потом приходит ваш босс и выбрасывает яблоко в окно. Сейчас вы работаете над новым проектом, и у этого компьютера еще нет текстовых возможностей. Никто. Нет шрифтов. Ничего.

Теперь давайте закончим эту программу. Рассчитайте и отобразите первые 20 символов числа Пи, не используя шрифты, которые не являются частью вашей программы. Ваш вывод может быть отображен или записан в стандартный формат в виде файла изображения (jpeg, png, gif, svg (если вы не используете никаких символов), bmp, xpm). Вы можете использовать любой язык, но вы не можете использовать функции шрифта вашего языка, отображение текста или подобное.

небольшой бонус (10 символов), если он будет работать на Лизу.

Редактировать: для тех, кто не понял, мое вдохновение было первым Mac, и название каламбур. Большое спасибо @Sukminder, чей анимированный GIF просто классный. Конкурс не заканчивается, если приходит лучший ответ.

hildred
источник
Мне нравится этот вызов, но технически такая система также не способна отображать исходный код? За исключением Пита, конечно.
Приближается к
2
@ValekHalfHeart вы можете загрузить исходный код с другого компьютера
Джон Дворжак
1
А как вы определяете читабельность человека? Например, мой почерк доступен для чтения некоторым людям (по крайней мере, одному), а другим - нет. (Кстати, 2 ^ (2x2) = 16, достаточно глифов для всех 11 цифр.;))
Кендалл Фрей
4
Я вообще не понимаю заголовок, я не понимаю, как ASCII-искусство может быть нормальным, когда мы не можем использовать отображение текста, и вопрос очень нуждается в определении «вычислить PI».
Питер Тейлор
2
Что на самом деле означает «вычислить пи»? Могу ли я жестко закодировать растровое изображение первых 20 десятичных знаков? (Не использует встроенную константу PI или аналогичную)
FireFly

Ответы:

6

Питон, 222 символа

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

Первая строка вычисляет цифры числа пи с использованием приближения pi-3 ~= 277991633/1963319607. Следующие три строки выводят 20 символов пи с использованием ASCII art Nemeth Braille.

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

Здесь я раздвигаю границы в двух направлениях, как в «вычислении Пи», так и в «читабельном» смысле.

Кит Рэндалл
источник
3
Какого черта? Я думал, что мы не должны использовать какой-либо текстовый вывод. Как ваш компьютер будет отображать *и пробелы без шрифта?
Boothby
@boothby: это искусство ASCII. Представьте *себе черный пиксель 1x1 и `` белый пиксель 1x1.
Кит Рэндалл
1
У него есть точка. Вы не можете визуализировать *без использования шрифтов, я думаю, что вы дисквалифицированы
Сирены
18

Python, 217 байт

Требуется библиотека изображений 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()

Подсчет байтов предполагает, что экранированный символ \177заменяется его буквальным эквивалентом (символ 127 ).

Вывод будет выглядеть следующим образом (он откроется в вашей стандартной программе просмотра * .bmp):

Обратите внимание, что это может быть легко параметризовано для печати любого количества цифр, которые вам нравятся. Следующее примет целочисленный ввод из stdin и отобразит столько цифр:

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

Выход для n = 80 :


Расчет Пи

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

Да, это так. Формула используется результат применения Эйлера Transform к серии Лейбница , а затем факторизуя каждый член от остальной части суммы. Формула сходится линейно; каждая цифра требует log 2 (10) ≈ 3,32 итерации. Для тех, кто заинтересован в деривации, см. Приложение А.

дисплей

PIL используется для генерации изображений, потому что это самая удобная из известных мне библиотек. Создается пустое черно-белое растровое изображение размером 141 × 11 , а затем на нем рисуются белые линии семисегментным способом, по одному пикселю за раз. Позиции, необходимые для рисования каждого сегмента, хранятся в строке битовой маски с битами, соответствующими следующим позициям:

 000
3   5
3   5
 111
4   6
4   6
 222

Бит магии (j%7/5*4-~j%7/4*~j/7+p,j%7*3%14%8+j%14/10+2)производит каждый пиксель в следующем порядке (base-18):

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

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

Приложение

Преобразование Эйлера - это метод ускорения сходимости, который работает для любой серии, которая показывает абсолютную монотонную сходимость. Результирующий ряд будет сходиться линейно, обычно со скоростью один бит на член (обратите внимание, что если исходный ряд уже был суперлинейным, результирующий ряд будет на самом деле сходиться медленнее). Чисто математическое описание немного трудно следовать, так что я буду принимать процедурный подход.

Начнем с серии Лейбница:

Затем разделите каждый член пополам, комбинируя соседние термины:

Упрощенная:

Обобщенная:

Обратите внимание, что у ведущего ½ не было партнерского термина, и, следовательно, он был исключен из остальной суммы. Это первый член преобразованной серии. Чтобы найти следующий термин, мы повторяем процесс снова:

И опять:

И опять:

И еще раз для хорошей меры:

На данный момент у нас есть первые пять слагаемых, и шестой член очевиден. Этого должно быть достаточно для обобщения, поэтому мы остановимся здесь. Начнем с факторизации числителей и знаменателей:

Знаменатели , очевидно , содержат двойной факториал из 2n + 1 , так что мы будем латать , что:

Все подходит, за исключением первых двух слагаемых, которые имеют неучтенные 2 в знаменателе. Мы можем исправить это, умножив все выражение на 2 :

2 3 = 2 · 4 , поэтому:

Числитель теперь может быть легко идентифицирован как n! ,

Обратите внимание, что коэффициент, добавляемый к каждому последующему члену, n / (2n + 1) , приближается к 1/2, когда n становится большим, что подразумевает линейную сходимость со скоростью один бит на член - это на самом деле задумано. Хороший результат, но без факториалов было бы еще лучше. Здесь мы можем отделить каждый последующий член от остальной суммы, что сгенерирует вложенное выражение:



Это может быть переписано как рекуррентное отношение:

Где n отсчитывается в обратном направлении от ⌈ log 2 (10) · d ⌉ .. 0 , где d - количество требуемых цифр.

Может быть интересно отметить, что стабильная точка этого повторения равна точно 2 (или 4, если вы удвоили его, как я сделал в приведенном выше разделе), поэтому вы можете сохранить несколько итераций, правильно инициализировав. Тем не менее, инициализация случайного значения, которое вам нужно в другом месте, и добавление нескольких дополнительных итераций вверху, как правило, обходится дешевле.

Примо
источник
1
Очень приятно, спасибо за урок! То , что я не получаю то , что pв p/2 * x/p + ...делают .. AIUI Python поддерживает автоматическое продвижение к BigInteger-иш типа данных, поэтому оно не должно быть прецизионной вещи, но почему - то те , pS дела и не отменяют , как я полагаю , их ... что мне здесь не хватает?
FireFly
@FireFly pинициализируется нечетно, так что p/2/pэквивалентно - при целочисленном делении - ((p-1)/2)/p. Это производит 1/3, 2/5, 3/7и т.д. термины , полученные выше.
Прим
12

#C - 777 символов

C - 731 символов

Печать GIF в stdout.

  • Причудливый: без запятой после первого 3.

Сшивание GIF из предварительно сконфигурированного заголовка + каждая цифра, представленная домашним шрифтом (встроенный) шрифта 5x5 пикселей.

Результат

введите описание изображения здесь

Это там --- ^

Обратите внимание, что GIF иногда исчезает в Chrome после одного запуска.

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

Краткое введение:

Расчет ИП

Pi рассчитывается с использованием слегка модифицированной версии реализации Дика Винтера и Ахима Фламменкампа алгоритма Рабиновича и Вагона для вычисления цифр π.

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

GIF поколения

GIF изображения имеет canvasсвойство в заголовке. Мы можем использовать это в сочетании с отображением нескольких изображений, устанавливая leftсвойства для каждой цифры соответственно - где каждая цифра является (встроенным) изображением сама по себе.

Документация.

Пример:

Header: Canvas Width  100 pixels
        Canvas Height   5 pixels

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

Расширенный код (с множеством комментариев)

Грязно, но это часть минимизации :

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

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

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

Хотите использовать более короткий / другой алгоритм для вычисления π.

Runium
источник
2
Я не вижу точку после первых 3 на изображении.
Виктор Стафуса
1
У вас есть ссылка на информацию об алгоритме генерации числа десятичных чисел? Я немного поигрался с твоим кодом (после удаления GIF), но я не понимаю, почему это приводит к цифрам числа пи ...
FireFly
7

JavaScript, 680 символов

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

Это можно посмотреть в веб-браузере; числа выводятся как пути SVG.

Снимок экрана вывода SVG в веб-браузере

  • Он не вычисляет пи интересным образом, и JS не хватает числового типа с точностью до 20 цифр.

  • Чтобы сохранить символы, я пропустил данные пути для «0», так как они не отображаются в последовательности.

JustinMimbs
источник
Ох, векторный подход. Очень хорошо, хорошая работа над шрифтом тоже.
FireFly
5

Java - 866 860 857 853 символа, плюс читерская версия с 574 символами

Используя формулу Симона Плуффа с 1996 года, выводится x.pngфайл с белыми цифрами в виде цифровых часов на черном фоне:

число Пи

Это сжатый код:

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

Вот с идентификацией и некоторыми пробелами было бы так:

import java.math.BigDecimal;

class E {

    static java.awt.Graphics g;

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

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

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

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

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

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

Обманывая правила и учитывая, что вычисление PI может быть выполнено как «числовое представление строки 3.1415926535897934384», это можно уменьшить до 574 символов:

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

Java - 642 622 символа

Копирование из моего предыдущего ответа, используя формулу Симона Плуффа от 1996 года. Но вместо этого выводит 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));}}

Все это с некоторой идентификацией и пробелами, а также с некоторой помощью для читателя, чтобы понять значение магических чисел:

import java.math.BigDecimal;

class H {

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

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

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

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

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

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

Выход:

###         #  # #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  ###  # #  
  #         #  # #    #  #    # #    #  #    #      #  #    # #  # #    #  # #    #    #    #  # #  # #  
###         #  ###    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###  ###  
  #         #    #    #    #    #  #    # #    #    #    #  # #    #    #    #    #  #      #  # #    #  
###   #     #    #    #  ###  ###  ###  ###  ###  ###  ###  ###  ###    #  ###  ###  ###  ###  ###    # 
Виктор Стафуса
источник
4

С 253 250 символов

Аппроксимирует число pi, используя алгоритм в коде @ Sukminder (беззастенчиво заимствуя и немного реорганизуя свой код). Выводит двоичное изображение PBM , которое затем можно преобразовать, например, с помощью 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);}

Вот как выглядит вывод с моим рендером PPM на основе Брайля:

Скриншот вывода

Имеет ту же причуду, что и ответ @ Sukminder в том, что в нем отсутствует десятичный разделитель. Кроме того, мой вывод является вертикальным, и можно ли предположить, что он читается человеком ...

Изменить: применены предложения @ Угорен.

Светляк
источник
Крошечные улучшения: перейти putsк for инициализации, определить L[5]и опустить ,0. Сделайте dпараметр main(сохранить запятую).
Угорен
4

PHP 380

требуется GD включен для вывода изображения

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

введите описание изображения здесь

Пи вычисление: поскольку базовый php имеет точность по умолчанию 14, и я не хотел перекомпилировать сервер с включенными расширениями произвольной точности, я даже не смог приблизить PI с требуемыми десятичными знаками, поэтому вместо этого он вычисляет tau / 2, а затем остальные десятичные дроби

так как графика состоит из 0 и 1, я могу попробовать использовать WBMP в качестве формата позже, чтобы посмотреть, смогу ли я удалить gd

Einacio
источник
это изображение красное на черном и действительно маленькое, но при 500% вы можете прочитать его, если присмотритесь. (и не дальтоники.)
hildred
@hildred каждый символ 3x5 with 1 px between chars. цвет красный только для того, чтобы уменьшить 4 символа, но, учитывая, что я не выиграю, я
поменяю
Мой комментарий был задуман не как критика, а как объяснение, чтобы поднять голоса.
hildred
Сохранит ли imagecreateindex какие-либо символы? такая функция существует?
hildred
@hildred при работе с pallete image ( imagecreate), первый вызов imagecolorallocateустанавливает цвет фона, а второй - для установки цвета письма. так дольше кончается
Einacio
4

Принтер C + LaserWriter 599 - 10 = 589

Передайте вывод на ваш LaserWriter! :) Это должно работать на Лизе (с компилятором C).

Он вычисляет piв принтере, вычисляя сумму длин отрезков, которые приблизительно соответствуют последовательности кривой Безье, которая приблизительно равна половине окружности, деленной на диаметр, умноженной на 2.

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

Ungolfed Level-1 (1985-совместимый) PostScript:

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

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

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

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

Выход:

ps_pi

Люзер Дрог
источник
Полагаю, мне тоже нужно сделать шрифт.
luser droog
Хм. Никогда не собираюсь получать достаточно цифр таким образом. PS имеет только 32-битные числа с плавающей запятой.
Люзер Дрог
классная идея, мне нравится постскриптум для игры в гольф.
hildred
У меня есть растровый шрифт для цифр, но гольф просто испортит его!
luser droog
2

Java, 1574 2643 1934 символов

Сжатые символы 1934 года :

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

Расширено 2643 символа:

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

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

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

    int loc = 0;

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

    }
}

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

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

}

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

Метод Пи взят из: /programming/8343977/calculate-pi-on-an-android-phone?rq=1

Clayton
источник
Похоже, вы использовали константу вместо расчета PI.
Хильдред
Это хороший поворот. Работаю над этим сейчас.
Клейтон
Вы можете сжать его немного больше, добавляя throws Exceptionв mainи извлекать блок примерочных поймать. Кроме того, вы можете переименовывать piи sqrtметоды и loc, args, SCALE, x0и x1переменные в 1 идентификаторов гольцов. И, кстати, вы должны добавить полный класс, включая class Foo{объявление и импорт.
Виктор Стафуса