Resim Dizesi


18

Biraz arka plan:

Brainf * ck'i ilk öğrendiğimde, yaptığım ilk şeylerden biri, bir dizeye girecek bir Java uygulaması yazmak ve söz konusu dizeyi yazdırmak için biraz optimize edilmiş bir program oluşturmaktı.

Son zamanlarda Piet ile oynuyorum ve aynı şeyi yapmakla oynuyorum. Piet'in bu zorluğa biraz katkıda bulunan oldukça ilginç bir dil olduğunu fark ettim.

Bu yüzden, SE'deki arkadaşlarıma meydan okumak istedim. Bu dil ile neler yapabileceğinizi görelim.

Meydan okuma

ASCII karakterlerinin boş olmayan bazı dizelerini alan bir program veya işlev yazın. Dizeyi, dizeyi yazdıracak ve sonlanacak bir Piet programı oluşturacak şekilde işleyin.

Çıktı sizin için en uygun formatta bir piet kaynağı görüntüsüdür. PNG tercih edilir, ancak zorunlu değildir.

Piet işlevselliği burada test edilebilir .

Piet kodu zorunluluk çıktı dize kendisi üretir. Kullanıcıların girmesine izin verilmez.

Aşağıda görüldüğü gibi yalnızca Piet-Onaylı renkler kullanılabilir:

piet renkler

Bu bir popülerlik yarışması olduğu için kazananlar oylamaya göre seçilecek. Bağlar kaynak kod boyutuna göre kesilecektir.

Bonus puanlar, çıktı görüntülerinin yaratıcılığına bağlı olarak kendi takdirime bağlı olarak verilecektir. Sonuçta bunlar resimler.

Yanıtlar:


9

C, (78 + 26 * strlen) kodları

Bu, çoğunlukla komşu hatlarda renk çarpışması olasılığı nedeniyle optimize etmek şaşırtıcı derecede zordu.

Karakterler temel 12'ye dönüştürülür, böylece her karakter 2 basamaklı bir sayıdır. Her standart satır aşağıdakileri içerir: işaretçi (şimdi tek satırlar için sağ, çift satırlar için sol), çoğalt (ilk olarak yığında bulunan 12 sayısı), itme (1. basamak), çarpma, itme (2. basamak), ekle , outc, push (tek satırlar için 1, çift satırlar için 3), çoğaltma, boşluk, işaretçi (şimdi satırın sonunda aşağı doğru).

Komşu hatlarda renk çarpışmalarını önlemek için, boşluk doldurma işleminden sonra durum hatırlanır ve bir çarpışma olursa nesil buna geri alınır. Bir sonraki deneme bir sonraki renkle başlar.

"Merhaba Piet!" İçin çıktı:

Merhaba

asciipiet2.c

#include "img.h"

#define WIDTH 26
#define OP(op, h, d) int op() { hue += h; dark += d; hue %= 6; dark %= 3; return setp(); }
#define CCMP(c1, c2) (((c1).r == (c2).r) && ((c1).g == (c2).g) && ((c1).b == (c2).b))
#define OPCNT(op) if(op) continue

Color piet[6][2] =
{
    {{0xff, 0xc0, 0xc0}, {0xff, 0x00, 0x00}, {0xc0, 0x00, 0x00}},
    {{0xff, 0xff, 0xc0}, {0xff, 0xff, 0x00}, {0xc0, 0xc0, 0x00}},
    {{0xc0, 0xff, 0xc0}, {0x00, 0xff, 0x00}, {0x00, 0xc0, 0x00}},
    {{0xc0, 0xff, 0xff}, {0x00, 0xff, 0xff}, {0x00, 0xc0, 0xc0}},
    {{0xc0, 0xc0, 0xff}, {0x00, 0x00, 0xff}, {0x00, 0x00, 0xc0}},
    {{0xff, 0xc0, 0xff}, {0xff, 0x00, 0xff}, {0xc0, 0x00, 0xc0}}
};

Color white = {0xff, 0xff, 0xff};

Image img;
int hue, dark, x, y, dx = 1;

void nextline()
{
    x -= dx;
    dx = -dx;
    y += 1;
}

int setp()
{
    if(y > 0 && CCMP(piet[hue][dark], imgGetP(img, x, y - 1)))
    {
        return 1;
    }
    imgSetP(img, x, y, piet[hue][dark]);
    x += dx;
    return 0;
}

void whiteto(int to)
{
    if(dx == 1)
    {
        while(x < to) imgSetP(img, x++, y, white);
    }
    else
    {
        while(x >= WIDTH - to) imgSetP(img, x--, y, white);
    }
}

OP(fill,    0, 0)
OP(pushraw, 0, 1)
OP(pop,     0, 2)
OP(add,     1, 0)
OP(sub,     1, 1)
OP(mul,     1, 2)
OP(divi,    2, 0)
OP(mod,     2, 1)
OP(not,     2, 2)
OP(gt,      3, 0)
OP(pnt,     3, 1)
OP(sw,      3, 2)
OP(dup,     4, 0)
OP(roll,    4, 1)
OP(in,      4, 2)
OP(inc,     5, 0)
OP(out,     5, 1)
OP(outc,    5, 2)

int push(int num);
int pushn(int num)  { int i; for(i = 0; i < num - 1; ++i) { if(fill()) return 1; } return pushraw(); } 
int push0()         { return (push(1) || not()); }
int push8()         { return (push(2) || dup() || dup() || mul() || mul()); }
int push9()         { return (push(3) || dup() || mul()); }
int push10()        { return (push(9) || push(1) || add()); }
int push11()        { return (push(9) || push(2) || add()); }
int push(int num)
{
    switch(num)
    {
    case 0:  return push0();
    case 8:  return push8();
    case 9:  return push9();
    case 10: return push10();
    case 11: return push11();
    default: return pushn(num);
    }
}

int main(int argc, char* argv[])
{
    char* str;
    int len, i;

    if(argc != 2)
    {
        printf("Usage: %s \"string to print\"\n", argv[0]);
        return -1;
    }

    str = argv[1];
    len = strlen(str);

    imgCreate(img, WIDTH, len + 3);

    fill(); push(4); push(3); mul(); push(1); dup(); whiteto(WIDTH - 2);
    for(i = 0; i < len; ++i)
    {
        int var, sx = x, sy = y, sdx = dx, fin = 0, off = rand();
        for(var = 0; var < 18 && !fin; var++)
        {
            x = sx; y = sy; dx = sdx;
            hue = ((var + off) % 18) / 3; dark = ((var + off) % 18) % 3;

            OPCNT(fill()); OPCNT(pnt());
            nextline(); pnt(); dup();
            OPCNT(push(str[i] / 12)); OPCNT(mul()); OPCNT(push(str[i] % 12)); OPCNT(add()); OPCNT(outc()); OPCNT(push(2 - dx)); if(i != len - 1) { OPCNT(dup()); }
            whiteto(WIDTH - 2);
            fin = 1;
        }
        if (!fin)
        {
           printf("collision unavoidable\n");
           return -1;
        }
    }
    x -= dx;
    {
        int var, sx = x, sy = y, sdx = dx, fin = 0;
        for(var = 0; var < 18 && !fin; var++)
        {
            x = sx; y = sy; dx = sdx;
            hue = var / 3; dark = var % 3;
            OPCNT(fill()); OPCNT(pnt()); OPCNT(fill());
            fin = 1;
        }
        if (!fin)
        {
            printf("collision unavoidable\n");
            return -1;
        }
    }
    x -= 2 * dx;
    y += 1;
    imgSetP(img, x, y, white);
    x -= dx;
    y += 1;
    hue = 0; dark = 1;
    fill(); fill(); fill();

    imgSave(img, "piet.pnm");

    return 0;
}

img.h

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct
{
   unsigned char r;
   unsigned char g;
   unsigned char b;
} Color;

typedef struct
{
   Color* data;
   int width;
   int height;
} Image;

#define imgCreate(img, w, h)           {\
                                          int length;\
                                          (img).width = (w);\
                                          (img).height = (h);\
                                          length = (img).width * (img).height * sizeof(Color);\
                                          (img).data = malloc(length);\
                                          memset((img).data, 0, length);\
                                       }

#define imgDestroy(img)                {\
                                          free((img).data);\
                                          (img).width = 0;\
                                          (img).height = 0;\
                                       }

#define imgGetP(img, x, y)             ((img).data[(int)(x) + (int)(y) * (img).width])

#define imgSetP(img, x, y, c)          {\
                                          (img).data[(int)(x) + (int)(y) * (img).width] = c;\
                                       }

#define imgLine(img, x, y, xx, yy, c)  {\
                                          int x0 = (x), y0 = (y), x1 = (xx), y1 = (yy);\
                                          int dx =  abs(x1 - x0), sx = x0 < x1 ? 1 : -1;\
                                          int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;\
                                          int err = dx + dy, e2;\
                                          \
                                          for(;;)\
                                          {\
                                             imgSetP((img), x0, y0, c);\
                                             if (x0 == x1 && y0 == y1) break;\
                                             e2 = 2 * err;\
                                             if (e2 >= dy) {err += dy; x0 += sx;}\
                                             if (e2 <= dx) {err += dx; y0 += sy;}\
                                          }\
                                       }

#define imgSave(img, fname)            {\
                                          FILE* f = fopen((fname), "wb");\
                                          fprintf(f, "P6\n%d %d\n255\n", (img).width, (img).height);\
                                          fwrite((img).data, sizeof(Color), (img).width * (img).height, f);\
                                          fclose(f);\
                                       }

#define imgLoad(img, fname)            {\
                                          FILE* f = fopen((fname), "rb");\
                                          char buffer[16];\
                                          int index = 0;\
                                          int field = 0;\
                                          int isP5 = 0;\
                                          unsigned char c = ' ';\
                                          while(field < 4)\
                                          {\
                                             do\
                                             {\
                                                if(c == '#') while(c = fgetc(f), c != '\n');\
                                             } while(c = fgetc(f), isspace(c) || c == '#');\
                                             index = 0;\
                                             do\
                                             {\
                                                buffer[index++] = c;\
                                             } while(c = fgetc(f), !isspace(c) && c != '#' && index < 16);\
                                             buffer[index] = 0;\
                                             switch(field)\
                                             {\
                                                case 0:\
                                                   if (strcmp(buffer, "P5") == 0) isP5 = 1;\
                                                   else if (strcmp(buffer, "P6") == 0) isP5 = 0;\
                                                   else fprintf(stderr, "image format \"%s\" unsupported (not P5 or P6)\n", buffer), exit(1);\
                                                   break;\
                                                case 1:\
                                                   (img).width = atoi(buffer);\
                                                   break;\
                                                case 2:\
                                                   (img).height = atoi(buffer);\
                                                   break;\
                                                case 3:\
                                                   index = atoi(buffer);\
                                                   if (index != 255) fprintf(stderr, "image format unsupported (not 255 values per channel)\n"), exit(1);\
                                                   break;\
                                             }\
                                             field++;\
                                          }\
                                          imgCreate((img), (img).width, (img).height);\
                                          if (isP5)\
                                          {\
                                             int length = (img).width * (img).height;\
                                             for(index = 0; index < length; ++index)\
                                             {\
                                                (img).data[index].r = (img).data[index].g = (img).data[index].b = fgetc(f);\
                                             }\
                                          }\
                                          else\
                                          {\
                                             fread((img).data, sizeof(Color), (img).width * (img).height, f);\
                                          }\
                                          fclose(f);\
                                       }

5

C, (384 + 256 * strlen) kodek, optimizasyon yok

Bu çözümde akıllı bir saldırı yok. Her karakter, piksel = ascii değeri olarak yüksekliği olan tek bir satırla temsil edilir. Op sekansı daha sonra push, outc, push, outc, ...

"Merhaba Piet!" İçin çıktı (ve üst kısmın yakınlaştırılması):

pınar

asciipiet.c

#include "img.h"

Color piet[6][3] = {
    {{0xff,0xc0,0xc0},{0xff,0x00,0x00},{0xc0,0x00,0x00}},
    {{0xff,0xff,0xc0},{0xff,0xff,0x00},{0xc0,0xc0,0x00}},
    {{0xc0,0xff,0xc0},{0x00,0xff,0x00},{0x00,0xc0,0x00}},
    {{0xc0,0xff,0xff},{0x00,0xff,0xff},{0x00,0xc0,0xc0}},
    {{0xc0,0xc0,0xff},{0x00,0x00,0xff},{0x00,0x00,0xc0}},
    {{0xff,0xc0,0xff},{0xff,0x00,0xff},{0xc0,0x00,0xc0}}
};

Color white = {0xff,0xff,0xff};

int main(int argc, char* argv[])
{
    char* str;
    int len, i, hue, dark;
    Image out;

    if(argc != 2)
    {
        printf("Usage: %s \"string to print\"\n", argv[0]);
        return -1;
    }

    str = argv[1];
    len = strlen(str);

    imgCreate(out, len * 2 + 3, 128);

    hue = 0;
    dark = 1;
    for(i = 0; i < len; i++)
    {
        imgLine(out, i * 2, 0, i * 2, str[i] - 1, piet[hue][dark]);
        dark = (dark + 1) % 3;
        imgSetP(out, i * 2 + 1, 0, piet[hue][dark]);
        dark = (dark + 2) % 3;
        hue = (hue + 5) % 6;
    }
    imgSetP(out, len * 2, 0, piet[hue][dark]);
    imgSetP(out, len * 2 + 1, 0, white);
    imgSetP(out, len * 2 + 2, 0, white);
    imgSetP(out, len * 2 + 2, 1, white);
    imgSetP(out, len * 2 + 2, 2, white);
    imgSetP(out, len * 2 + 2, 3, white);
    imgSetP(out, len * 2 + 1, 3, white);
    imgSetP(out, len * 2, 2, piet[0][4]);
    imgSetP(out, len * 2, 3, piet[0][5]);
    imgSetP(out, len * 2, 4, piet[0][6]);

    imgSave(out, "piet.pnm");

    return 0;
}

img.h

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct
{
   unsigned char r;
   unsigned char g;
   unsigned char b;
} Color;

typedef struct
{
   Color* data;
   int width;
   int height;
} Image;

#define imgCreate(img, w, h)           {\
                                          int length;\
                                          (img).width = (w);\
                                          (img).height = (h);\
                                          length = (img).width * (img).height * sizeof(Color);\
                                          (img).data = malloc(length);\
                                          memset((img).data, 0, length);\
                                       }

#define imgDestroy(img)                {\
                                          free((img).data);\
                                          (img).width = 0;\
                                          (img).height = 0;\
                                       }

#define imgGetP(img, x, y)             ((img).data[(int)(x) + (int)(y) * (img).width])

#define imgSetP(img, x, y, c)          {\
                                          (img).data[(int)(x) + (int)(y) * (img).width] = c;\
                                       }

#define imgLine(img, x, y, xx, yy, c)  {\
                                          int x0 = (x), y0 = (y), x1 = (xx), y1 = (yy);\
                                          int dx =  abs(x1 - x0), sx = x0 < x1 ? 1 : -1;\
                                          int dy = -abs(y1 - y0), sy = y0 < y1 ? 1 : -1;\
                                          int err = dx + dy, e2;\
                                          \
                                          for(;;)\
                                          {\
                                             imgSetP((img), x0, y0, c);\
                                             if (x0 == x1 && y0 == y1) break;\
                                             e2 = 2 * err;\
                                             if (e2 >= dy) {err += dy; x0 += sx;}\
                                             if (e2 <= dx) {err += dx; y0 += sy;}\
                                          }\
                                       }

#define imgSave(img, fname)            {\
                                          FILE* f = fopen((fname), "wb");\
                                          fprintf(f, "P6\n%d %d\n255\n", (img).width, (img).height);\
                                          fwrite((img).data, sizeof(Color), (img).width * (img).height, f);\
                                          fclose(f);\
                                       }

#define imgLoad(img, fname)            {\
                                          FILE* f = fopen((fname), "rb");\
                                          char buffer[16];\
                                          int index = 0;\
                                          int field = 0;\
                                          int isP5 = 0;\
                                          unsigned char c = ' ';\
                                          while(field < 4)\
                                          {\
                                             do\
                                             {\
                                                if(c == '#') while(c = fgetc(f), c != '\n');\
                                             } while(c = fgetc(f), isspace(c) || c == '#');\
                                             index = 0;\
                                             do\
                                             {\
                                                buffer[index++] = c;\
                                             } while(c = fgetc(f), !isspace(c) && c != '#' && index < 16);\
                                             buffer[index] = 0;\
                                             switch(field)\
                                             {\
                                                case 0:\
                                                   if (strcmp(buffer, "P5") == 0) isP5 = 1;\
                                                   else if (strcmp(buffer, "P6") == 0) isP5 = 0;\
                                                   else fprintf(stderr, "image format \"%s\" unsupported (not P5 or P6)\n", buffer), exit(1);\
                                                   break;\
                                                case 1:\
                                                   (img).width = atoi(buffer);\
                                                   break;\
                                                case 2:\
                                                   (img).height = atoi(buffer);\
                                                   break;\
                                                case 3:\
                                                   index = atoi(buffer);\
                                                   if (index != 255) fprintf(stderr, "image format unsupported (not 255 values per channel)\n"), exit(1);\
                                                   break;\
                                             }\
                                             field++;\
                                          }\
                                          imgCreate((img), (img).width, (img).height);\
                                          if (isP5)\
                                          {\
                                             int length = (img).width * (img).height;\
                                             for(index = 0; index < length; ++index)\
                                             {\
                                                (img).data[index].r = (img).data[index].g = (img).data[index].b = fgetc(f);\
                                             }\
                                          }\
                                          else\
                                          {\
                                             fread((img).data, sizeof(Color), (img).width * (img).height, f);\
                                          }\
                                          fclose(f);\
                                       }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.