Моделюйте стільниковий автомат Wireworld


24

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

Ваша місія полягає у створенні найкоротшого впровадження Wireworld вашою мовою на вибір.

Кожна комірка в сітці має одне з чотирьох станів. Чотири стани - "порожній", "мідний", "головка електронів" або "електронний хвіст".

  • Порожня клітина завжди залишатиметься порожньою клітиною
  • Голова електрона завжди стане хвостом електронів
  • Хвіст електронів завжди стане мідним
  • Мідна клітина стане електронною головкою, якщо рівно один-два з восьми її сусідів будуть електронними головками, інакше вона залишиться мідною

Цей конкурс матиме подібний стиль до змагань Найкоротша гра життя , але з кількома змінами.

  • Сітка повинна бути не менше 40 на 40 комірок
  • Краї сітки НЕ повинні обмотуватися (не тором). Поставтеся до клітин поза полем як до постійно "порожніх".
  • Користувачі повинні мати можливість вводити власну стартову конфігурацію.
  • Дивитись на порожні екрани - це не цікаво. Програма повинна візуально відображати моделювання під час роботи.

Це кодовий гольф, виграє найменше байт.

Відповіді:


6

APL, Dyalog (131)

{h t c←1↓⍵∘=¨F←' htc'⋄⎕SM∘←1 1,⍨⊂N←F[1+⊃+/H h(t∨c≠H←c∧S↑1 1↓1 2∊⍨⊃+/+/K∘.⊖(K←2-⍳3)∘.⌽⊂¯1⌽¯1⊖h↑⍨2+S←25 79)ר⍳3]⋄∇N⊣⎕DL÷4}↑{79↑⍞}¨⍳25

Вихід відображається у ⎕SMвікні. Моделювання працює нескінченно. Сітка 79x25, тому що це розмір ⎕SMвікна за замовчуванням . Голова електрона єh , хвіст є t, мідь є c. Програма зчитує стартову конфігурацію з клавіатури як 25 рядків.

Пояснення:

  • ↑{79↑⍞}¨⍳25: прочитати сітку 79x25
  • h t c←1↓⍵∘=¨F←' htc': дістаньте три матриці, одна з головами, одна з хвостами та одна з мідною. Також встановіть F на рядок' htc' .

  • ⎕SM∘←1 1,⍨⊂N←F[1+⊃+/... ר⍳3]: Частина "..." - це вектор довжини три, де елементи є матрицями, що показують нові голови, хвости та мідь відповідно. Голову множимо на 1, хвости на 2, а мідь на 3, потім ці матриці підсумовуємо разом і додаємо одну, даючи в матрицю індексів F. Nстає новим станом, у тому ж форматі, що і вхідний, і він відображається на⎕SM екрані, починаючи з верхнього лівого кута.

  • ¯1⌽¯1⊖h↑⍨2+S←25 79: Додайте рамку пробілів до h , зростаючи її на два ряди та стовпчики, потім обертаючи її вправо і вниз.

  • ⊃+/+/K∘.⊖(K←2-⍳3)∘.⌽⊂: Обертайте матрицю у всіх восьми напрямках, а потім підсумовуйте отримані матриці разом, даючи кількість сусідів, які є головами на кожній позиції.

  • 1 2∊⍨: Встановіть лише ті позиції, які мають 1 або 2 сусідів.

  • S↑1 1↓: Видаліть межу, яку ми додали раніше.

  • H←c∧: Нові головки - це всі ті мідні клітини, які мають 1 або 2 головних сусіди.

  • t∨c≠H: Нові мідні клітини - це всі старі хвости, і всі старі мідні клітини, які не стали головами.

  • H h(... ): Нові голови єH як обчислено вище, нові хвости - старі голови, а нові мідні клітини - як розраховано вище.

  • ∇N⊣⎕DL÷4: Зачекайте 1/4 секунди, а потім знову запустіть функцію N.


Я думаю, що було б краще, якби вона могла містити сітку 40 на 40.
mbomb007

6

АЛПАКА, 82 ч

ALPACA - мова, спеціально розроблена для стільникових автомати.

o - ніщо; c - провідник; e - електрон; t - електронний хвіст.

state o " ";
state c "c" to e when 1 e or 2 e;
state e "e" to t;
state t "t" to c.

Коли була випущена ця мова? Чи є посилання на мову?
Оптимізатор

@Optimizer Ось ви йдете! Я не склав мови.
DanTheMan

4
Класно. Правильна мова для правильного виклику ..
Optimizer

4

GolfScript ( 125 120 105 100 символів)

n%{.,,{1${.0=,:w[1,*]\+2*>3<}:^~`{zip^''+.4=5%'`X '@{+}*(7&1>'iX'>+=}+w,%}%"\033[H\033[J"@n*+puts 6.?.?}do

Зауважте, що я рахую \033як один символ кожного, тому що вони можуть бути замінені буквальним ESCсимволом. При цьому використовуються коди управління ANSI, тому покладається на сумісний tty. Також зауважте, що кадри друкуються починаючи з вхідної сітки.

Існує деяке перекриття із створенням сітки сум , яка також використовує сусідство Мура.

Кодування: порожній пробіл => ; головка електронів => i; електронний хвіст => `; мідь => X.

Пауза між ітераціями - час, необхідний для обчислення 46656 46656 . Перехід 6.?.?на інший вираз дозволяє контролювати швидкість; Наступний повільний для того ж числа символів - 7.?.?це набагато повільніше (вихід у 22 рази більший, і це не лінійний підрахунок складності).

Для тестового випадку я використовував

`iXXXXXXXXX
X   X      
   XXX     
X   X      
i`XX XXXXXX

від виклику Кодексу Розетти Wireworld .


3

Пітон 371 341 символів

Так, це не так вже й коротко, але в ньому є інтерактивна гія!

import matplotlib.pylab as l,scipy.ndimage as i
r=round
w=l.zeros((40,40),int)-1
p=l.matshow(w,vmax=2)
c=p.figure.canvas
def h(e):
 try:w[r(e.ydata),r(e.xdata)]=[0,2,-1][e.button-1]
 except:x=i.convolve(w==2,l.ones((3,3)),int,'constant');w[:]=w/2+((w==0)&(x>0)&(x<3))*2
 p.set_data(w);c.draw()
c.mpl_connect('button_press_event',h)
l.show()

Інструкції:

Клацніть лівою кнопкою миші, щоб розмістити провід

Клацніть правою кнопкою миші, щоб очистити

Клацніть середньою кнопкою миші, щоб розмістити голову електронів

Клацніть за межами осей, щоб перейти до автомата


(x>0)&(x<3)-> (0<x<3). :)
beary605

3

Пітон ( 243) 214)

Намагався зробити перехрес між зручністю та персонажами. Сітка 40х40. Введення подано на stdin. Голова електрона є h, електронний хвіст є t, мідь є c, все інше порожнє.

import os
f=raw_input()
while 1:f=''.join('h'if(i=='c')&(0<sum(1 for i in[-1,1,-39,-40,-41,39,40,41]if f[e+i:e+i+1]=='h')<3)else't'if i=='h'else'c'if i=='t'else f[e]for e,i in enumerate(f));os.system('cls');print f

Цикл while (рядок 3) нестиснений (не буде працювати, якщо його розмістити в коді):

while 1:
 for e,i in enumerate(f):
  if(i=='c')&(0<sum(1 for i in[-1,1,-39,-40,-41,39,40,41]if f[e+i:e+i+1]=='h')<3):f[e]='h'
  elif i=='h':f[e]='t'
  elif i=='t':f[e]='c'
  else:f[e]=f[e]  #redundant, but Python needs this to run
 os.system('cls') #cls is shorter than clear, so I used that
 print f

Я думаю , ви можете замінити рядки 5-7 з одним виразом: g[e]='h'if(t=='c')&...else't'if i=='h'else'c'if i=='t'else i. Не впевнений, чи працює це точно так, як є, але щось у цьому напрямку має спрацювати
Strigoides

2

C, 355 347 300 294 символів

Редагувати: зрозумів, що мені не потрібно feof()

Редагувати: Збережено 47 символів! Вилучив сон, позбувся майже всіх брекетів, поєднав безліч операцій.

Редагувати: Останнє сьогодні, оскільки я зламав 300 символів. Змінено printfнаputs , знайшли милі маленькі оптимізації з першим порівнянням.

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

Введення - це текстовий файл з назвою i. Він містить представлення початкового стану, з *міддю, +для електронної головки, -для електронного хвоста, пробілів для порожніх комірок. Я використовую ворота XOR зі сторінки вікі для тестування.

   ****-+**
  +        ******
   -*******      *
                ****
                *  *****
                ****
   ********      *
  +        ******
   -****+-*

char*p,t[42][42],s[42][42];
main(i,r,c,n,j)
{
  for(p=fopen("i","r");fgets(s[i++]+1,40,p););

  for(;;getch(),memcpy(s,t,1764))
    for(j=1;j<41;puts(s[j++]+1))
      for(i=1;i<41;)
      {
        p=t[j]+i;
        r=s[j][i++];
        *p=r==43?45:r;
        if(r==45)
          *p=42;
        if(r==42)
          for(r=-1,n=0;r<2;++r,*p=n&&n<3?43:42)
            for(c=-2;c<1;)
              n+=s[j+r][i+c++]==43;
      }
}

Можна cond?43:42написати 42+(cond)? І я впевнений, що r=s[j][i++];*p=r==43?45:r;if(r==45)*p=42;можна звестись, r=s[j][i++];*p=r==43?45:r==45?42:r;якщо неr=s[j][i++]-43;*p=!r?45:r==2?42:r;
Пітер Тейлор

1

Пітона, 234 218 символів

import time
I=input
C=I()
H=I()
T=I()
R=range(40)
while 1:
 for y in R:print''.join(' CHT'[(C+H+2*T).count(x+y*1j)]for x in R)
 H,T=[c for c in C if 0<sum(1 for h in H if abs(c-h)<2)<3and c not in H+T],H;time.sleep(.1)

Ви вводите дошку як три списки складних чисел, що представляють координати комірок міді (які повинні включати списки голів та хвостів), голів та хвостів. Ось приклад:

[3+2j+x for x in range(8)] + [3+4j+x for x in range(8)] + [11+3j+x for x in range(6)] + [2+3j]
[3+2j]
[2+3j]

Зауважте, що ми evalвводимо, тому ви можете використовувати довільно складні вирази для списків складних чисел.


1

QBasic, 309 байт

Попередження: версія для гольфу не є зручною для користувачів: вона має дивний метод введення, працює як нескінченний цикл і не має затримок (таким чином, працює занадто швидко в деяких системах). Запускайте його, лише якщо ви знаєте, як припинити програму у вашому середовищі QBasic. Рекомендована версія без вогків (див. Нижче).

INPUT w,h
SCREEN 9
FOR y=1TO h
FOR x=1TO w
PSET(x,y),VAL(INPUT$(1))
NEXT
NEXT
DO
FOR y=1TO h
FOR x=1TO w
SCREEN,,0
c=POINT(x,y)
d=c
IF c=7THEN d=1
IF c=1THEN d=6
IF c=6THEN
n=0
FOR v=y-1TO y+1
FOR u=x-1TO x+1
n=n-(POINT(u,v)=7)
NEXT
NEXT
d=7+(n=0OR n>2)
END IF
SCREEN,,1,0
PSET(x,y),d
NEXT
NEXT
PCOPY 1,0
LOOP

Для запуску вкажіть у вікні запиту ширину wта висоту вашої конфігурації h. 1 Потім введіть w*hодноцифрові коди для комірок (рухаючись ліворуч направо, потім зверху вниз), за допомогою

  • 0 = порожній
  • 6 = дріт
  • 7 = сигнальна голова
  • 1 = сигнальний хвіст

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

Безумовно

Більш зручна версія. Щоб змінити макет, змініть DATAоператори в кінці.

Код використовує перевагу POINTфункції, яка зчитує значення кольору пікселя з екрану. Це означає, що нам не потрібно зберігати комірки окремо як масив. Щоб переконатися, що всі осередки оновлюються одночасно, ми виконуємо оновлення на другій "сторінці". Ми можемо переключити активну сторінку за допомогою версії SCREENтвердження та скопіювати вміст однієї сторінки до іншої за допомогою PCOPYоператора.

SCREEN 9

EMPTY = 0 ' Black
HEAD = 7  ' Light gray
TAIL = 1  ' Blue
WIRE = 6  ' Brown/orange

' First two data values are the width and height
READ w, h
' The rest are the initial configuration, row by row
' Read them and plot the appropriately colored pixels
FOR y = 1 TO h
  FOR x = 1 TO w
    READ state$
    IF state$ = "" THEN value = EMPTY
    IF state$ = "H" THEN value = HEAD
    IF state$ = "T" THEN value = TAIL
    IF state$ = "W" THEN value = WIRE
    PSET (x, y), value
  NEXT x
NEXT y

' Loop the simulation until user presses a key
DO UNTIL INKEY$ <> ""
  ' Store current time for delay purposes
  t# = TIMER

  FOR y = 1 TO h
    FOR x = 1 TO w
      ' Active page = display page = 0
      SCREEN , , 0
      ' Get the color value of the pixel at x,y
      oldVal = POINT(x, y)
      IF oldVal = EMPTY THEN
        newVal = EMPTY
      ELSEIF oldVal = HEAD THEN
        newVal = TAIL
      ELSEIF oldVal = TAIL THEN
        newVal = WIRE
      ELSEIF oldVal = WIRE THEN
        neighbors = 0
        FOR ny = y - 1 TO y + 1
          FOR nx = x - 1 TO x + 1
            IF POINT(nx, ny) = HEAD THEN neighbors = neighbors + 1
          NEXT nx
        NEXT ny
        IF neighbors = 1 OR neighbors = 2 THEN
          newVal = HEAD
        ELSE
          newVal = WIRE
        END IF
      END IF
      ' Active page = 1, display page = 0
      SCREEN , , 1, 0
      ' Plot the new value on page 1
      PSET (x, y), newVal
    NEXT x
  NEXT y

  ' Copy page 1 to page 0
  PCOPY 1, 0

  ' Delay
  WHILE TIMER >= t# AND t# + 0.2 > TIMER
  WEND
LOOP

DATA 8,5
DATA T,H,W,W,W,W,W,W
DATA W, , , ,W, , , 
DATA  , , ,W,W,W, , 
DATA W, , , ,W, , , 
DATA H,T,W,W, ,W,W,W

1 Максимальні значення ширини та висоти залежать від режиму екрану. В SCREEN 9, ширина може бути до 638, а висота до 348.SCREEN 7 Має меншу роздільну здатність (максимальний розмір конфігурації 318 на 198), але пікселі є більшими і тому їх легше бачити (на DOS QBasic або емуляторі DOSBox - на жаль QB64 просто дає менше вікно).

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

Невикористана версія на archive.org , у режимі екрану 7:

Wireworld в QBasic

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