Життя може бути барвистим!


30

Кожній клітці в життєвому стільниковому автоматі потрібен лише один біт, щоб представити її, оскільки вона може бути лише живою або мертвою. Це означає, що є лише два кольори; досить нудно.

Звичайні зображення мають 24 біти на піксель (8 у кожному RGB). Це означає, що в звичайному зображенні з пікселями як клітинками ви могли б імітувати одразу 24 життєвих ігри!

Виклик

Ваше завдання - написати програму, яка застосує одне покоління правил життєздатного стільникового автомата до зображення 24-бітової глибини (у будь-якому відомому форматі, який вам подобається), і виведе отримане зображення.

Кожен з 24 шарів буде використовувати той самий життєвий набір правил, строго всередині власного шару. 24 шари не взаємодіють один з одним.

Також

  • Нулі - це мертві клітини, а одні - живі клітини.
  • Граничні умови періодичні (утворюють торус).
  • Будь-які розміри зображення повинні працювати.

Введення-виведення

Вашій програмі потрібно взяти 3 аргументи через stdin або командний рядок (або найближчий еквівалент вашої мови):

  1. Назва файлу вхідного зображення.
  2. Рядок цифр від 0 до 8 у порядку зростання, який позначає, коли народжуються нові комірки:
    • Якщо цифра d знаходиться в рядку, то мертві клітини оживають, коли у них є d живі сусіди.
    • Приклад: 3нормальне життя - мертві клітини з точно трьома живими сусідами оживають.
  3. Рядок цифр від 0 до 8 у порядку зростання, який позначає, коли існуючі клітини виживають:
    • Якщо цифра d знаходиться в рядку, то живі клітини з d живими сусідами доживають до наступного покоління, інакше вони гинуть.
    • Приклад: 23нормальне життя - до наступного раунду виживають лише клітини з рівно 2 або 3 сусідами.

Зауважте, що сусідство Мура завжди використовується. Прочитайте це чи це для отримання додаткової інформації про те, що точно визначає життєвий автомат та багато цікавих наборів правил.

Вихідне зображення 1 покоління пізніше має бути відображене або збережене як out.png( bmpабо будь-яке інше).

Подання

Виграє найкоротший код у байтах.

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

Якщо вам подобається, ви можете скористатися цією пістолетом Gosper Glider, де єдині живі шматочки містяться в зеленому шарі 128 (він працює лише у звичайному житті):

планер-пістолет

Настійно рекомендується розміщувати цікаві послідовності чи навіть анімації.


1
Я думаю, що це дублікат - єдині нові частини читаються в іншому файловому форматі та розбивають шари - обидва є основними і не викликають труднощів самі по собі.
Говард

1
@Howard Але вам не цікаво бачити зображення?

3
Так. PPCG.SE - це місце болю і агонії, а не веселощів і гарних образів . Якщо він ставить бонусну ідею вимогою, то напевно питання має бути досить оригінальним?
Флонк

3
Ясна зацікавленість громади полягає в тому, щоб програми не копіювались із незначними змінами у відповідях на інші запитання. Цей сайт не працює на основі "Я думаю, що це може бути весело, тому це нормально". Це 4chan.
Пітер Тейлор

4
@Howard Я вже не вважаю, що це дублікат. Звичайно, якщо codegolf.stackexchange.com/questions/34505/simulate-rule-110 та codegolf.stackexchange.com/questions/4370/… можуть співіснувати, то це зовсім не дублікат.
Захоплення Кальвіна

Відповіді:


16

МАТЛАБ: 275

Мій улюблений з параметрів, які я спробував, це те 45678, 568що після поступового розпаду виходить у небо мерехтливі зірки. Цей образ зображує "розпад стійкості пам'яті".

Невикольований gif-виробляє код (приймає PNG без розширення):

B = input('B', 's') - 48;
S = input('S', 's') - 48;
f0 = input('file: ', 's');
frames = 60;

f = sprintf('%s.png',f0);
fout = sprintf('%s.gif',f0);
first = 1;
img = imread(f);
for i = 1:60
    out = img * 0;
    [r, c, turd] = size(img);
    for b=0:7
        bimg = ~~bitand(img,2^b);
        pimg = [bimg,bimg,bimg;bimg,bimg,bimg;bimg,bimg,bimg];
        fun = @(ro,co) pimg(r+ro:r+r+ro-1,c+co:c+c+co-1,:);
        sum = fun(0,0)+fun(0,1)+fun(0,2)+fun(1,0)+fun(1,2)+fun(2,0)+fun(2,1)+fun(2,2);
        bnew = uint8(bimg & ismember(sum,S) | ~bimg & ismember(sum, B));
        out = out + 2^b * bnew;
    end
    %imwrite(out,'out.png');
       if first
           [img1,img2] = rgb2ind(img,256);
           imwrite(img1,img2,fout,'gif','Loop',Inf);
          imwrite(img1,img2,fout,'gif','WriteMode','append');
           first = 0;
       end
       img = out;
       [img1,img2] = rgb2ind(img,256);
       imwrite(img1,img2,fout,'gif','WriteMode','append');%,'DelayTime', 2*delay);
end

Код для гольфу, який приймає повне ім'я файлу (який може бути GIF, JPEG та, можливо, інші речі) і пише в out.png:

I=@()input('','s');B=I();S=I();i=imread(I());o=0;[r,c,t]=size(i);for b=0:7
g=~~bitand(i,2^b);p=repmat(g,3);F=@(z,Z)p(r+z:r+r+z-1,c+Z:c+c+Z-1,:);M=@(A)ismember(F(0,0)+F(0,1)+F(0,2)+F(1,0)+F(1,2)+F(2,0)+F(2,1)+F(2,2),A-48);o=o+2^b*uint8(g&M(S)|~g&M(B));end
imwrite(o,'out.png')

Раніше виявили той факт, що параметри 12, 1можуть бути використані для створення килима Серпінського як фрактал. Ось один з випадково розміщеною точкою насіння у кожному біті:


14

Математика, 359

i=InputString;f=Transpose;b=(p=FromDigits/@Characters@#&)@i[];s=p@i[];Map[FromDigits[#,2]&/@#~ArrayReshape~{3,8}&,f[(g=#;{#,Total[g~RotateRight~#&/@Drop[Join@@Table[{i,j},{i,-1,1},{j,-1,1}],{5}],1]}~f~{3,1,2}/.{l_,n_}:>Boole[l<1&&!b~FreeQ~n||l>0&&!s~FreeQ~n])&/@Apply[Join,IntegerDigits[ImageData[Import@i[],y="byte"],2,8],{2}]~f~{2,3,1},{3,1,2}],{2}]~Image~y

Я беру дані з рядкових підказок у порядку (1) правила народження, (2) правила виживання, (3) ім'я файлу, і результат відображаю прямо в Mathematica.

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

Ось дещо незворушена версія:

i = InputString;
f = Transpose;
b = (p = FromDigits /@ Characters@# &)@i[];
s = p@i[];
Map[
  FromDigits[#,2] & /@ #~ArrayReshape~{3, 8} &,
  f[
   (
      g = #;
      {#, 
         Total[g~RotateRight~# & /@ 
           Drop[Join @@ Table[{i, j}, {i, -1, 1}, {j, -1, 1}], {5}], 
          1]}~f~{3, 1, 2} /. {l_, n_} :> 
        Boole[l < 1 && ! b~FreeQ~n || l > 0 && ! s~FreeQ~n]
      ) & /@ 
    Apply[Join, 
      IntegerDigits[ImageData[Import@i[], y = "byte"], 2, 8], {2}]~
     f~{2, 3, 1},
   {3, 1, 2}
   ],
  {2}
  ]~Image~y

Ось два приклади використання аватара Rainbolt :

Rainbolt

20 поколінь, що використовують стандартну Гра життя [3,23]:

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

20 поколінь, що використовують [456,34567]:

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

І ось GIF перших 200 поколінь останнього правила. GIF пропускає кожен третій кадр, тому що я не міг стиснути його нижче 2 Мб:

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


2
яке цікаве правило
гордий haskeller

10

Пітон 2, 427

Для тих, хто не має Mathematica;)

import Image as I
t=raw_input
r=range
A=I.open(t())
G=map(int,t())
S=map(int,t())
w,h=A.size
B=I.new('RGB',(w,h))
A=[[map(int,("{:08b}"*3).format(*A.load()[x,y]))for y in r(h)]for x in r(w)]
for x in r(w):
 for y in r(h):
  p=''
  for i in r(24):
    c=A[x][y][i]
    n=sum(A[(x+k-1)%w][(y+j-1)%h][i]for j in r(3)for k in r(3))-c
    p+=str(~~[n in G,n in S][c])
  B.load()[x,y]=tuple(int(p[i*8:i*8+8],2)for i in r(3))
B.save('out.bmp')

Це вимагає ввести ім'я файлу, потім випадки народження, потім випадки виживання. Таким чином , для нормальних правил життя ви могли б вхід test.bmp, потім 3, потім 23(без лапок або що - небудь не потрібно).

Я використовував форматування рядків для індексації та рекомбінації бітових кольорів, хоча, мабуть, це не оптимально.

Зауважте, що це досить повільно.

Приклад

Високе життя та чудове мистецтво поєднуються так? (Правило 36/ 23.)

Mona Lisa Original покоління 1 Оригінал / Покоління 1

покоління 2 покоління 3 Покоління 2 / Покоління 3


6

Java, 1085 байт

import java.awt.image.*;import java.io.*;import javax.imageio.*;class F{static int n(boolean[][][]a,int x,int y,int z){int k=0;for(X=Math.max(x-1,0);X<Math.min(x+2,w);X++)for(Y=Math.max(y-1,0);Y<Math.min(y+2,h);Y++)if(a[X][Y][z])k++;return k-(a[x][y][z]?1:0);}static int p(String k){return Integer.parseInt(k,2);}static int w,h,x,y,z,X,Y;public static void main(String[]a)throws Exception{BufferedImage i=ImageIO.read(new File(a[0]));w=i.getWidth();h=i.getHeight();boolean[][][]G=new boolean[w][h][24];for(x=0;x<w;x++)for(y=0;y<h;y++){String k="".format("%24s",Integer.toBinaryString(0xFFFFFF&i.getRGB(x,y)));for(z=0;z<24;z++){G[x][y][z]=k.charAt(z)>48;}}for(x=0;x<w;x++)for(y=0;y<h;y++){String r="",g="",b="",k;for(z=0;z<8;){k=""+n(G,x,y,z);r+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}for(;z<16;){k=""+n(G,x,y,z);g+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}for(;z<24;){k=""+n(G,x,y,z);b+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}i.setRGB(x,y,new java.awt.Color(p(r),p(g),p(b)).getRGB());}ImageIO.write(i,"png",new File("out.png"));}}

Приклади (правило 368/245):

Gen 0:

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

Gen 1:

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

Gen 2:

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

Gen 3:

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

Gen 4:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.