Моделюйте будь-який 1D стільниковий автомат


14

Змагання

Ви повинні написати повну програму, яка займає сім номерів від STDIN і друкує двовимірну історію стільникового автомата (CA) до STDOUT. Це код гольфу.

Форматування вводу Вхід буде складати сім цілих рядків / рядків, розділених комами. Перше число - це номер правила згідно коду Wolfram (стандартна назва для кожного правила). Друга - це початкова конфігурація запуску. Третій і четвертий описують, який шаблон і скільки разів його слід додати зліва від стартової конфігурації. як підкладка. П’ятий і шостий зробити те ж саме для правого боку. Останнє число - це кількість поколінь для запуску моделювання.

Отже, прикладом введення є 90,11,0,4,0,4,5. Це повинно сказати вашій програмі, що ви використовуєте правило 90 . Він також повинен сказати програмі, що ви хочете, щоб початкова конфігурація була 11з рядком, 0доданим 4 рази до обох кінців, тому фактична початкова схема є 0000110000. Він також говорить вашій програмі запустити це моделювання протягом 5 поколінь.

Вихідна програма Ваша програма повинна надрукувати весь масив комірок кожного покоління (відокремлених новими рядками), щоб вихід був просторово-часовою діаграмою CA. Для кожного покоління стан кожної комірки визначається її станом та станами комірок зліва та справа, відповідно до правила, поданого як вхідне. Моделювання має обернутись по краях. Першим, що надрукується, має бути стартовий масив як gen. 0.

Вхід 90,11,0,4,0,4,5повинен дати максимально точний наступний результат.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

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

Більше прикладів

вхід:

184,1100,01,2,01,1,4

вихід:

0101110001
1011101000
0111010100
0110101010
0101010101

вхід:

0,1011,1,0,0,1,2

вихід:

10110
00000
00000

Детальніше про те, як працює 1D CA та як вони нумеровані


Молодці для включення правила 0 до тестового випадку.
Пітер Тейлор

Мене захоплює, що правило 90 - це прокладка Серпінського. Тим більше, що це було частиною тестування, яке я зробив для іншого проекту Codegolf .
JoeFish

@JoeFish Саме цей образ змусив мене спробувати це. Я хотів зробити відповідь 8086 - вбити 2 птахів - але, ймовірно, знадобляться струнні операції, тому мій емулятор не міг би її запустити (поки).
luser droog

Хтось це вже робив: pouet.net/prod.php?which=60478
luser droog

Відповіді:


5

Гольфскрипт, 77 73 70 символів

','/)~\(~:?;~~*@@~*@+\+{1&}/]({[.,{.[3<?256+]{2base}/\~=\(+}*])n@)\+}*

Дякуємо @Howard, який вказав, як зберегти 4 символи.


Можна зберегти очевидний 48--> 1&а я думаю також ще три. Ви можете опустити )перед блоком (не збільшувати лічильник), а також зберегти останні два спливаючі вікна.
Говард

@Howard, спасибі Ці попи в кінці були корисними для попередньої ітерації, але ви праві, що їх усунення має сенс зараз.
Пітер Тейлор

5

APL (153 символи)

∇ cellularautomaton
  i               ← ⍞
  s               ← (i=',') / ⍳ ⍴i
  (b a x c)       ← {i[s[⍵]↓⍳s[⍵+1]-1]} ¨ ⍳4
  (z x x l x r n) ← ⍎i
  y               ← ⍎ ¨ ⊃ ,/ (l / ⊂a) , b , r / ⊂c
  (n+1) (⊃⍴,y) ⍴ '01'[1+⊃ ,/ y,{({(z ⊤⍨ 8/2)[8 - 2⊥¨ 3 ,/ (⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y} ¨ ⍳n]
∇

І в менш читаному, трохи коротшому вигляді:

i←⍞⋄s←(i=',')/⍳⍴i⋄b a x c←{i[s[⍵]↓⍳s[⍵+1]-1]}¨⍳4⋄z x x l x r n←⍎i⋄y←⍎¨⊃,/(l/⊂a),b,r/⊂c⋄'01'[1+⊃,/y,{({(z⊤⍨8/2)[8-2⊥¨3,/(⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y}¨⍳n]⍴⍨(1+n),⊃⍴,y

Приклад:

      cellularautomaton
26,00110,01,4,10,6,7
0101010100110101010101010
1000000011100000000000001
0100000110010000000000011
0010001101101000000000110
0101011001000100000001101
0000010110101010000011000
0000100100000001000110100
0001011010000010101100010

Я впевнений, що є можливість для вдосконалення (я навіть знайшов кілька змін під час написання цього допису!), Але деякі з них можуть спричинити кардинальні зміни, і я не можу більше дивитися на APL. Тут застосовується варіант APL - Dyalog APL .


4

Рубі, 165 159 символів

a=gets.split ?,
b=a.map &:to_i
c=(x=a[2]*b[3]+a[1]+a[4]*b[5]).chars.map &:hex
(0..b[6]).map{puts c*''
c=(1..w=x.size).map{|i|b[0]>>c[i-1]*2+c[i%w]+c[i-2]*4&1}}

Редагувати: я знайшов місця для невеликих вдосконалень.

Приклад виконання:

> 30,1,0,20,0,20,20
00000000000000000000100000000000000000000
00000000000000000001110000000000000000000
00000000000000000011001000000000000000000
00000000000000000110111100000000000000000
00000000000000001100100010000000000000000
00000000000000011011110111000000000000000
00000000000000110010000100100000000000000
00000000000001101111001111110000000000000
00000000000011001000111000001000000000000
00000000000110111101100100011100000000000
00000000001100100001011110110010000000000
00000000011011110011010000101111000000000
00000000110010001110011001101000100000000
00000001101111011001110111001101110000000
00000011001000010111000100111001001000000
00000110111100110100101111100111111100000
00001100100011100111101000011100000010000
00011011110110011100001100110010000111000
00110010000101110010011011101111001100100
01101111001101001111110010001000111011110
11001000111001111000001111011101100010001

3

C, 303 305 301 294 292

305 Правка: на жаль. Забув, що calloc()займає дві арги. Це підірвало на більший вхід.

301 Редагувати: Ах ХА! Використовував мій calloc()boo-boo, щоб зберегти ще 2 байти, збільшивши розмір блоку запитуваної пам'яті.

294 Редагувати: Зламали 300! Видалили одну з strcat()s і підкрутили кілька петель. Треба використовувати максимальний прийом, який так само весело сказати, як використовувати.

292 Редагувати: Не потрібно було +2виділення пам'яті.

Я використовував відповідь luser droog як основну ідею, але змінив алгоритм обгортання, а також багато налаштувань та розбиття констант.

r,A,C,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);for(s=calloc(A+++C,9);A--;)strcat(s,A?a:b);for(;C--;)strcat(s,c);p=strdup(s);for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)for(j=C;j--;)p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;}

r,A,C,n,j;
main(){
    char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    for(s=calloc(A+++C,9);A--;)
        strcat(s,A?a:b);
    for(;C--;)
        strcat(s,c);
    p=strdup(s);
    for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)
        for(j=C;j--;)
            p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;
}

скріншот1

скріншот2


1
Ви забули змусити його почати C,A,! :)
luser droog

для навантажень пам’яті, а що brk()? то p=s+C+1;десь.
luser droog

1
+1 ще раз для використання +++!
luser droog

Ха-ха! Змінити все %[01]на %s! -9 (... через багато років)
luser droog

1
@luserdroog це не працює, оскільки% s жадібний і теж їсть коми і інші цифри.
JoeFish

2

C (487 484 418 із пробілами)

* Випав 66 за допомогою JoeFish *

C,A,r,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    s=malloc(strlen(a)*A+strlen(b)+strlen(c)*C+3);*s=0;
    strcat(s,"0");
    for(;A--;)strcat(s,a);
    strcat(s,b);
    for(;C--;)strcat(s,c);
    strcat(s,"0");
    p=malloc((C=strlen(s)-1)+2);
    for(;n--;){
    *s=s[C-1];
    s[C]=0;
    puts(s+1);
    s[C]=s[1];
    for(j=1;s[j+1];j++)
        p[j]=(1<<(s[j-1]-48)*4+(s[j]-48)*2+s[j+1]-48)&r?49:48;
    t=p;p=s;s=t;
    }
    s[C]=0;
    puts(s+1);
}

машинопис

Джош @ Z1 ~
$! м
зробити ca
cc ca.c -o ca
ca.c: 1: 1: попередження: визначення даних не має типу або класу зберігання
ca.c: У функції 'main':
ca.c: 2: 5: попередження: несумісне неявне декларування вбудованої функції 'scanf'
ca.c: 3: 7: попередження: несумісне неявне оголошення вбудованої функції 'malloc'
ca.c: 3: 14: попередження: несумісне неявне декларування вбудованої функції 'strlen'
ca.c: 4: 5: попередження: несумісне неявне декларування вбудованої функції 'strcat'

Джош @ Z1 ~
$ відлуння 90,11,0,4,0,4,5 | ca
-bash: ca: команда не знайдена

Джош @ Z1 ~
$ відлуння 90,11,0,4,0,4,5 | ./ca
0000110000
0001111000
0011001100
0111111110
1100000011
0110000110


Приємно. Ви можете поголити досить багато байтів, зробивши свої intзмінні глобальними та видаливши #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish

Збережіть купу в forпетлях:for(;A--;)strcat(s,a);
JoeFish

І повторно використовуйте Aта Cпізніше, щоб не потрібно було декларувати iабо Bвзагалі. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Вибачте, я зараз зупинюся :)
JoeFish

Гаразд, я збрехав, ще один. Позбавтеся від 2 прощань, усунувши --C;: p=malloc((C=strlen(s)-1)+2);. Я думаю, що гольф-код цікавіше, ніж придумувати його в першу чергу!
JoeFish

Я не був впевнений у видаленні, #includeоскільки scanfце різноманітно. Але це, мабуть, нормально, оскільки його називають лише один раз. ... Моя стара машина померла вчора, і я все ще встановлюю Cygwin. Я включу ці зміни, як тільки зможу її перевірити. Спасибі!
luser droog
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.