дурні обмеження і пустеля


18

Отже, ви сиділи за своїм столом, займаючись програмою для обчислення перших 20 цифр пі, а разом з цим приходить ваш бос і викидає ваше яблуко у вікно. Зараз ви працюєте над новим проектом, і цей комп’ютер ще не має жодної текстової можливості. Немає. Без шрифтів. Нічого.

Тепер закінчимо цю програму. Обчисліть та відобразіть перші 20 символів pi, не використовуючи шрифтів, які не входять до вашої програми. Ваш вихід може бути відображений або записаний у стандартному форматі як файл зображення (jpeg, png, gif, svg (доки ви не використовуєте жодні символи), bmp, xpm). Ви можете використовувати будь-яку мову, але ви не можете використовувати функції шрифту, відображення тексту тощо.

невеликий бонус (10 символів) Якщо він буде працювати на Лізі.

Правка: для тих, хто цього не зрозумів, моє натхнення було першим мак, а назва - каламбур. Великий кудо на @Sukminder, чий анімований gif просто крутий. Конкурс не закінчився, якщо прийде краща відповідь.


Мені подобається виклик, але технічно чи не була б така система нездатною відображати вихідний код? За винятком Піта, звичайно.
Наближення

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, використовуючи наближення pi-3 ~= 277991633/1963319607. Наступні три рядки виводять 20 символів pi за допомогою мистецтва ASCII Nemeth Braille.

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

Я штовхаю кордони у двох напрямках, як у «обчислювальному Пі», так і в «людському читаному» почутті.


3
Якого біса? Я думав, що ми не повинні використовувати жодне текстове виведення. Як ваш комп'ютер візуалізує поля *та пробіли без шрифту?
кабінка

@boothby: Це мистецтво ASCII. Подумайте *як про чорний піксель 1x1 і як про білий піксель 1x1.
Кіт Рендалл

1
У нього є бал. Ви не можете надати *без використання шрифтів, я думаю, що ви дискваліфіковані
Sirens

18

Пітон, 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замінено його буквальним еквівалентом (char 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

Так, це все. Використовувана формула є результатом застосування «Трансформації Ейлера» до серії Лейбніца , а потім вирахування кожного терміна з залишку суми. Формула сходиться лінійно; кожна цифра вимагає ітерацій журналу 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)створює кожен піксель у такому порядку (база-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

Додаток А

Трансформація Ейлера - техніка прискорення конвергенції, яка працює для будь-якої серії, яка демонструє абсолютну монотонну конвергенцію. Отриманий ряд буде сходитися лінійно, як правило, зі швидкістю один біт на термін (зауважте, що якщо початковий ряд вже був суперлінійним, то результуюча серія насправді буде сходитися повільніше). Чисто математичний опис трохи важко слідувати, так що я буду приймати процедурний підхід.

Почнемо з серії Leibniz:

Потім розділіть кожен термін навпіл, поєднуючи сусідні терміни:

Спрощено:

Узагальнено:

Зауважте, що ведучий ½ не мав партнерського терміну, і таким чином був виключений з решти суми. Це перший член трансформованого ряду. Щоб знайти наступний термін, ми повторюємо процес ще раз:

І знову:

І знову:

І ще раз для хорошої міри:

На даний момент у нас є перші п’ять термінів, і шостий термін очевидний. Цього має бути достатньо для узагальнення, тому ми зупинимось тут. Почнемо з підрахунку чисельників та знаменників:

Знаменники, очевидно, містять подвійний коефіцієнт 2n + 1 , тому ми будемо виправляти це в:

Все , припадки, в протягом перших двох термінів , які мають невраховані , за винятком 2 в знаменнику. Ми можемо це виправити, помноживши весь вираз на 2 :

2 3 = 2 · 4 , так:

Чисельник тепер можна легко ідентифікувати як n! .

Зауважте, що коефіцієнт, доданий до кожного наступного члена, n / (2n + 1) , наближається до ½, оскільки 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);}

Короткий вступ:

Розрахунок ПІ

Пі обчислюється за допомогою дещо модифікованої версії Dik Winter та реалізації Ахіма Фламменкампа алгоритму Рабіновіца та Вагона для обчислення цифр π.

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

Потрібно використовувати коротший / інший алгоритм для обчислення π.


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 у веб-браузері

  • Він не обчислює pi цікавим чином, і JS не вистачає типу цифри з точністю для відображення 20 цифр.

  • Щоб зберегти символи, я пропустив дані шляху для "0", оскільки вони не відображаються в послідовності.


О-о, векторний підхід. Дуже гарна, хороша робота і на шрифті.
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

C, 253 250 символів

Наближає пі, використовуючи алгоритм у коді @ 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);}

Ось як виглядає вихід з моїм рендером на основі Брайля:

Знімок екрана

Має таку саму хитрість, що і у відповіді @ Sukminder, що у ній немає десяткового роздільника. Крім того, вихід шахти є вертикальним, і чи можна його читати людиною, можна суперечити ...

Редагувати: застосовано пропозиції @ ugoren.


Крихітні вдосконалення: переходимо 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);

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

pi розрахунок: оскільки базовий php має стандартну точність 14, і я не хотів перекомпілювати сервер з увімкненими довільними розширеннями точності, я не міг навіть призначити PI необхідними десятковою комою, тому замість цього він обчислює тау / 2, а потім решта десяткових знаків

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


це зображення червоне на чорному та дійсно невелике, але на 500% ви можете його прочитати, якщо придивитесь. (і не є кольоровими
слідами

@hildred кожен символ є 3x5 with 1 px between chars. колір червоний просто для зменшення 4 символів, але враховуючи, що я не виграю, я зміню його на білий для читабельності
Einacio

Мій коментар мав на меті не як критику, а як пояснення для заохочення голосів.
hildred

Чи збереже imagecreateindex будь-які символи? чи існує така функція?
hildred

@hildred під час роботи з зображенням піддону ( imagecreate), перший виклик imagecolorallocateзадає колір тла, а другий потрібен для встановлення кольору написання. тому закінчується довше
Ейнасіо

4

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

Трубопровід на ваш LaserWriter! :) Це повинно працювати над Lisa (із компілятором 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 Рівень-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-бітні плавці.
luser droog

класна ідея, мені подобається постскрипт для гольфу.
hildred

У мене є шрифт растрової карти для цифр, але гольф просто зіпсує його!
luser droog

2

Ява, 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


Схоже, ви використовували константу замість обчислення PI.
hildred

Це приємний поворот. Працюємо над цим зараз.
Клейтон

Ви можете стиснути його трохи більше, додаючи throws Exceptionв mainі витягувати блок примірочних зловити. Крім того, ви можете перейменовувати piі sqrtметоди і loc, args, SCALE, x0і x1змінні в 1 ідентифікаторів гольців. І до речі, ви повинні додати повний клас, це включає class Foo{декларацію та імпорт.
Віктор Стафуса
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.