Имитация сотового автомата Wireworld

24

Wireworld - это сотовый автомат, который был разработан, чтобы напоминать электроны, протекающие через провода. Его простая механика позволяет строить цифровые схемы. Это даже позволило построить целый компьютер .

Ваша миссия - создать самую короткую реализацию Wireworld на выбранном вами языке.

Каждая ячейка в сетке имеет одно из четырех состояний. Четыре состояния являются «пустыми», «медными», «электронными головками» или «электронными хвостами».

  • Пустая ячейка всегда будет оставаться пустой ячейкой
  • Голова электрона всегда станет хвостом электрона
  • Хвост электрона всегда станет медью
  • Медная ячейка станет электронной головкой, если ровно один или два из ее восьми соседей являются электронными головками, в противном случае она останется медью

Этот конкурс будет иметь стиль, аналогичный конкурсу Shortest Game of Life , но с некоторыми изменениями.

  • Сетка должна быть не менее 40 на 40 ячеек
  • Края сетки НЕ должны обтекать (не тор). Относитесь к клеткам вне поля как к постоянно «пустым».
  • У пользователей должна быть возможность ввести свою начальную конфигурацию.
  • Смотреть на пустые экраны не весело. Программа должна визуально отображать симуляцию во время ее работы.

Это код гольф, выигрывает наименьшее количество байтов.

PhiNotPi
источник

Ответы:

6

APL, Дьялог (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, которые имеют 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

ALPACA, 82 символа

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

о ничто; с - проводник; е - электрон; т - электронный хвост.

state o " ";
state c "c" to e when 1 e or 2 e;
state e "e" to t;
state t "t" to c.
DanTheMan
источник
Когда был выпущен этот язык? Есть ли ссылки на язык?
Оптимизатор
@ Оптимизатор Вот, пожалуйста ! Я не делал язык.
DanTheMan
4
Круто. Правильный язык для правильной задачи ..
Оптимизатор
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

Python 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

Python ( 243 214)

Пытался сделать пометку между юзабилити и символами. Сетка 40х40. Ввод дан на стандартный ввод. Голова 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
beary605
источник
Я думаю , вы можете заменить строки 5-7 с одним выражением: g[e]='h'if(t=='c')&...else't'if i=='h'else'c'if i=='t'else i. Не уверен, что это работает точно так, как есть, но что-то в этом роде должно работать
Strigoides
2

С 355 347 300 294 символа

Редактировать: понял, что мне не нужно feof()

Редактировать: Сохранено 47 символов! Убрал сон, избавился практически от всех брекетов, объединил много операций.

Изменить: последний сегодня, так как я сломал 300 символов. Изменено printfнаputs , нашли милые маленькие оптимизации с первым сравнением.

С не очень хорошо справляется с такой проблемой, но играть в гольф - это весело. Это довольно грубая реализация, но я хотел посмотреть, как далеко я смогу это сделать.

Ввод представляет собой текстовый файл с именем 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;
      }
}
JoeFish
источник
Может 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 = сигнальный хвост

Как только вы вошли во все ячейки, начнется симуляция (и будет продолжаться до тех пор, пока вы не убьете программу).

Ungolfed

Более удобная версия. Чтобы изменить макет, измените 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

DLosc
источник