Имитация правила 110

27

Правило 110 - это клеточный автомат с некоторыми интересными свойствами. Ваша цель - смоделировать правило 110, используя как можно меньше символов.

Для тех, кто не знает, правило 110 моделируется построчно в сетке. Каждый квадрат в линии сетки смотрит на квадраты выше, слева вверху и справа, чтобы определить, какой должна быть ячейка.

current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0

Ввод: числа от 0 до 39, представляющие верхний ряд n-го квадрата ввода, в любом приемлемом формате (строка, разделенная запятыми, список, аргументы функции). Для поддержки языков с 1 индексом числа также могут быть 1 индексированы и могут варьироваться от 1 до 40.

Пример ввода:

38,39

Вывод: сетка 40 x 40, представляющая работающие автоматы, включая первый ряд. Вы должны оставить 0 пустым, а 1 - любым видимым печатным символом. Задние пробелы разрешены, при условии, что фактическая сетка может быть разумно различена. В нижней части сетки может быть новая строка, но между линиями сетки не должно быть пустых линий.

Пример вывода:

                                  XX
                                 XXX
                                XX X
                               XXXXX
                              XX   X
                             XXX  XX
                            XX X XXX
                           XXXXXXX X
                          XX     XXX
                         XXX    XX X
                        XX X   XXXXX
                       XXXXX  XX   X
                      XX   X XXX  XX
                     XXX  XXXX X XXX

и т.п.

Примечание: подобный вопрос о 1D клеточных автоматах уже задавался, но я надеюсь, что, используя только одно правило, можно написать более короткие ответы.

qwr
источник
4
Обтекание шаблонов (т. Е. Проверяет ли крайняя левая ячейка крайнюю правую ячейку в строке над ней)?
Вентеро
4
Если это единственное число , то это клеточный автомат .
ClickRick
1
Ответы могут быть немного короче, чем Имитация любого 1D сотового автомата, потому что правило жестко закодировано, а не анализируется на входе, но в остальном ответы будут одинаковыми. Если бы это было другое правило, тогда был бы потенциал для экономии, но как, черт возьми, особый случай - мощное правило Тьюринга спасло бы что-либо по сравнению с общей реализацией?
Питер Тейлор
1
@ Ventero Они не в этой версии.
qwr
1
@BMO это старый вопрос, но поскольку в настоящее время консенсус заключается в том, чтобы разрешить гибкие форматы ввода, я изменю вопрос, чтобы разрешить его
qwr

Ответы:

8

CJam - 47

S40*l',/{i'!t}/{N40,S3$S++f{>3<2b137Yb='!^}}39*

Используется !для «1» клеток.

Попробуйте это на http://cjam.aditsu.net/

Объяснение:

S40*делает строку (массив) из 40 пробелов
l',/читает строку и разделяет запятую
{…}/выполняет блок для каждого элемента (числа в строковой форме)
- i'!tпреобразует число в целое число и устанавливает элемент в этой позиции в предыдущей строке (первоначально 40 пробелов ) к '!'
На данный момент мы получили первую строку.
{…}39*выполняет блок 39 раз
- Nдобавляет новую строку
- 40,создает массив [0 1… 39]
- S3$S++копирует предыдущую строку (позиция 3 в стеке) и дополняет ее пробелом с каждой стороны
- f{…}выполняет блок для {каждого числа из 0 до 39} и {заполненная строка}
- >3<берет фрагмент из 3 элементов из дополненной строки, начиная с текущего номера
- 2bконвертируется из базы 2; элементы, которые мы нарезали, не являются цифрами base-2, но символы преобразуются в их значения ASCII, а '' mod 8 равен 0 и '!' mod 8 равен 1
- 137Ybпреобразует 137 в основание 2 ( Y= 2), получая [1 0 0 0 1 0 0 1], который на 110 перевернут и отрицается (на 8 битах)
- ='!^получает соответствующую цифру base-2 ( Массив оборачивается так, что индекс берется по модулю 8) и записывает xor с помощью '!' символ, в результате чего «!» для 0 и '' для 1

aditsu
источник
17

Рубин, 113 символов

c=[0]*41
eval"[#{gets}].map{|i|c[i]=1}"+'
c=(0..39).map{|x|putc" X"[u=c[x]]
110[4*c[x-1]+2*u+c[x+1]]}<<0;puts'*40

Принимает вход на стандартный ввод. Чтобы использовать другое правило, просто замените 110в последней строке любое правило, которое вы хотите попробовать.

Пример:

$ ruby 110.rb <<< 38,39
                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X
Ventero
источник
8

Mathematica, 122 байта

f[a_]:=Riffle[CellularAutomaton[110,Array[If[MemberQ[ToExpression["{"<>a<>"}"],#-1],1,0]&,40],39]/.0->" "/.1->"X","
"]<>""

Да, вы можете рассматривать это как злоупотребление этой лазейкой , но а) эта лазейка довольно спорная, б) вопрос о Cellular Automaton требует ответа Mathematica (особенно одного о правиле 110) и в) ответ Ruby от Ventero в любом случае короче, поэтому я не согласен не думаю, что какой-либо вред причинен.

Большинство символов используются для разбора ввода и форматирования вывода. Фактический автомат моделируется с помощью

CellularAutomaton[110,initialGrid,39]

При этом используются периодические граничные условия (поэтому сетка оборачивается).

Мартин Эндер
источник
8

Питон - 141

i=input()
o=range(40)
l=''.join(' X'[c in i]for c in o)
for r in o:print l;l=''.join('X '[l[c-1:c+2]in('XXX','   ','X  ','','  ')]for c in o)

Запустить как например python 110.py <<< 38,39

Алекс Л
источник
3
['X',' ']можно изменить, 'X 'чтобы сохранить 5 символов.
Увлечения Кельвина
16
Мой любимый фрукт теперьo=range()
kitcar2000
7

q, 67 62 58 байт

Предполагается, что нет обтекания:

{40{not(2 sv'flip 1 0 -1 xprev\:x)in 0 4 7}\@[40#0b;x;~:]}

Старая версия

{40{not(flip(prev;::;next)@\:x)in 3 cut 111100000b}\@[40#0b;x;not]}
{40{not(flip 1 0 -1 xprev\:x)in 3 3#111100000b}\@[40#0b;x;~:]}
skeevey
источник
5

Питон, 186

def r(s,m=range(40)):
 s=[int(i in s)for i in m]
 for g in m:print''.join([' X'[i]for i in s]);s=[int(not''.join(map(str,s[i-1:i+2]if i else s[:2]))in'111 100 000 00'.split())for i in m]

Достойный, но, вероятно, не оптимальный.

Вы не указали, как вводится, поэтому я просто сделал функцию.

Пример использования:

г ([38,39])

Выход:

                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X
Кальвин Хобби
источник
Я определил ввод: в вашем случае вам придется использовать input () и отформатировать ввод, как указано в исходном сообщении.
qwr
5

Mathematica, 113 символов

Другой ответ Mathematica с помощью CellularAutomaton.

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];
alephalpha
источник
Интересно, как " "["X"][[#]]&работает?
Мартин Эндер
@ m.buettner " "["X"][[1]]есть "X"." "["X"][[0]]возвращает главу" "["X"] , а именно " ".
алефальфа
А ну понятно. Так что это просто сохранение символа для списков. Это действительно умно. Я думаю, вы могли бы добавить его в codegolf.stackexchange.com/questions/12900/…
Мартин Эндер
4

С - 178

Этот код зависит от того, что каждая строка в матрице хранится в непрерывной памяти. Кроме того, он не печатает первую строку, но печатает следующие 40, поскольку в правилах указана только сетка 40x40.

Отмеченный только для удобства чтения, в число байтов входит только необходимый код.

a[41][42],i,j,*t;
main(){
    while(scanf("%d,",&j)>0)
        a[i][j]=1;
    for(;i<40;i++,puts(""))
        for(j=0;++j<40;)
            t=&a[i][j],
            putchar((*(t+42)=1&(110>>(*(t+1)?1:0)+(*t?2:0)+(*(t-1)?4:0)))?88:32);
}
Allbeert
источник
3

Луа - 351

Не идеальный язык для игры в гольф.

s,n,t,u=arg[1],{},table.remove,table.insert
for i=1,40 do u(n,i,'.') end
for i in s:gmatch("%d+")do u(n,i,'x');t(n)end
function a(b) c="";for i=1,40 do c=c..b[i] end;print(c);return c end
for i=1,40 do z= n[40]..a(n)..n[1];for k=2,41 do y=string.sub(z,k-1,k+1);if y=="xxx"or y=="x.." or y=="..." then u(n,k-1,'.')else u(n,k-1,'x')end;t(n)end end
AndoDaan
источник
1
do u(n,i,'x')это намеренно, не так ли?
Стэн Струм
3

Haskell , 135 131 130 байтов

-1 байт благодаря Эрджану Йохансену (переупорядочение take 40)

Совершенно другой подход к ответу FrownyFrog, но примерно такой же длины:

(a?b)r=mod(b+r+b*r+a*b*r)2
r x=0:(zipWith3(?)x=<<tail$tail x++[0])
f y=take 40$map(" o"!!)<$>iterate r[sum[1|elem i y]|i<-[0..40]]

1

объяснение

4101

f y=                               [sum[1|elem i y]|i<-[0..40]]

40

    take 40$              iterate r

01

            map(" o"!!)<$>

r110zipWith3(?)

r x=0:(zipWith3(?)x=<<tail$tail x++[0])

(?)Оператор является наиболее интересной частью решения: Раньше я использовал логическое правило , производимое с картой Карна, но оказывается, есть еще более краткий способ:

(a?b)r=mod(b+r+b*r+a*b*r)2
ბიმო
источник
1
Сохраните байт, поставив take 40$перед map(" o"!!)<$>.
Орджан Йохансен
3

Шелуха , 31 28 байт

Ха, Хаск бьет Желе!

†!¨↑¨↑40¡ȯẊȯ!ḋ118ḋėΘ`:0M#ŀ40

Попробуйте онлайн!

Объяснение и Унгольфед

Прежде чем добавить объяснение, позвольте мне немного раскрутить это. Давайте сначала удалим различные композиции, добавим явные скобки и распакуем ¨↑¨строку. Также давайте заменим 40с 4для более читаемого объяснения:

†!"t "↑4¡(Ẋ(!ḋ118ḋė)Θ`:0)M#ŀ4  -- example input: [3]
                           ŀ4  -- lower range of 4: [0,1,2,3]
                         M     -- map over left argument
                          #    -- | count in list
                               -- : [0,0,0,1]
        ¡(              )      -- iterate the following indefinitely (example with [0,1,1,1])
                     `:0       -- | append 0: [0,1,1,1,0]
                    Θ          -- | prepend 0: [0,0,1,1,1,0]
          Ẋ(       )           -- | map over adjacent triples (example with  1 1 0
                  ė            -- | | create list: [1,1,0]
                 ḋ             -- | | convert from base-2: 6
                               -- | | convert 118 to base-2: [1,1,1,0,1,1,0]
                               -- | | 1-based index: 1
                               -- | : [1,1,0,1]
                               -- : [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1],[1,1,1,1],[1,0,0,1],...]
      ↑4                       -- take 4: [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1]]
†                              -- deep map the following (example with [1,1,0,1])
 !"t "                         -- | use each element to index into "t ": "tt t"
                               -- : ["   t","  tt"," ttt","tt t"]
ბიმო
источник
2

Java, 321 символов

Например, ввод передается как аргумент из командной строки java R 38,39

Я никогда не писал более запутанный код Java :-)

class R{public static void main(String[]a) {
Integer s=40;boolean[]n,o=new boolean[s];
for(String x:a[0].split(","))o[s.valueOf(x)]=s>0;
for(Object b:o){n=o.clone();
for(int j=0;j<s;j++){
boolean l=j>1&&o[j-1],r=o[j],c=j+1<s&&o[j+1];
n[j]=!(l&c&r|l&!c&!r|!(l|c|r));
System.out.print((r?"X":" ")+(j>s-2?"\n":""));
}o=n;}}}
Томаш Дворжак
источник
2

Обновление: исправьте пример вывода здесь (с 40 строками, а не 50): новый вывод ниже (для краткости удален предыдущий):

                                      xx
                                     xxx
                                    xx x
                                   xxxxx
                                  xx   x
                                 xxx  xx
                                xx x xxx
                               xxxxxxx x
                              xx     xxx
                             xxx    xx x
                            xx x   xxxxx
                           xxxxx  xx   x
                          xx   x xxx  xx
                         xxx  xxxx x xxx
                        xx x xx  xxxxx x
                       xxxxxxxx xx   xxx
                      xx      xxxx  xx x
                     xxx     xx  x xxxxx
                    xx x    xxx xxxx   x
                   xxxxx   xx xxx  x  xx
                  xx   x  xxxxx x xx xxx
                 xxx  xx xx   xxxxxxxx x
                xx x xxxxxx  xx      xxx
               xxxxxxx    x xxx     xx x
              xx     x   xxxx x    xxxxx
             xxx    xx  xx  xxx   xx   x
            xx x   xxx xxx xx x  xxx  xx
           xxxxx  xx xxx xxxxxx xx x xxx
          xx   x xxxxx xxx    xxxxxxxx x
         xxx  xxxx   xxx x   xx      xxx
        xx x xx  x  xx xxx  xxx     xx x
       xxxxxxxx xx xxxxx x xx x    xxxxx
      xx      xxxxxx   xxxxxxxx   xx   x
     xxx     xx    x  xx      x  xxx  xx
    xx x    xxx   xx xxx     xx xx x xxx
   xxxxx   xx x  xxxxx x    xxxxxxxxxx x
  xx   x  xxxxx xx   xxx   xx        xxx
 xxx  xx xx   xxxx  xx x  xxx       xx x
xx x xxxxxx  xx  x xxxxx xx x      xxxxx
xxxxxx    x xxx xxxx   xxxxxx     xx   x

Делая еще одну головоломку, я узнал кое-что интересное о вложении операторов в циклы в php, и внезапно они стали намного сложнее, чем я думал. Когда у меня появляется время, я считаю, что могу значительно превзойти этот счет. На данный момент, хотя он остается неизменным на уровне неконкурентных 408.


Моя версия php 408 символов:

Это была отличная головоломка. Я также провел целую вечность, играя с входами, поскольку это - захватывающие вещи, это должно быть сказано. В любом случае, вот моя версия PHP (которая далеко не так хороша, как некоторые из опубликованных ответов, но завершена. В 0-й позиции - только выше и выше справа, в 39-й позиции - только выше и выше слева, т.е. без переноса. Так что здесь моя версия:

<?php $a='38,39';$b='';$d=explode(',',$a);for($i=0;$i<40;++$i){$c=' ';
foreach($d as $k=>$v){if($v == $i){$c='x';}}$b.=$c;}echo $b."\n";
for($x=1;$x<41;++$x){$o='';for($i=1;$i<41;++$i){if(($i>1)AND(substr($b,$i-2,1)=='x')){
$l=1;}else{$l=0;}if((substr($b,$i-1,1))=='x'){$v=1;}else{$v=0;}if((substr($b,$i,1))=='x'){
$r=1;}else{$r=0;}if((($l+$v+$r)==2)OR(($v+$r)==1)){$o.='x';}else{$o.=' ';}}
echo $o."\n";$b=$o;}?>

Вы можете увидеть его и запустить здесь: http://codepad.org/3905T8i8

В начале вводится строка ввода: $ a = '38, 39 ';

Вывод следующий:

xx removed as was too long originally - had 50 lines, not 40 xx

Надеюсь тебе понравится !!!

PS Мне пришлось добавить несколько разрывов строк в код, чтобы вы могли видеть все это, а не растягивать его по всей странице с помощью полосы прокрутки.

Пол Дрюетт
источник
Ваш вывод имеет 50 строк
aditsu
Ах, это потому, что я играл с ним после того, как закончил и увидел, что случилось. Незначительное изменение правил имеет такие интересные последствия. Во всяком случае изменили его на 40 сейчас и извините за то, что пропустили это.
Пол Дрюетт
Вы также можете изменить вывод: p
aditsu
Исправил вывод и добавил новую ссылку на кодовую панель с правильным значением. Еще раз спасибо
Пол Дрюетт
2

Stax , 24 байта CP437

╦♥µ╤u{£┬íQ<;▀ΦΣ╢╕╚äZ↕áû↑

Запускать и отлаживать онлайн!

Использует кодовую точку 1 в CP437 для ячеек «1».

Отличный случай, чтобы показать силу этого языка.

объяснение

Для объяснения используется распакованная версия (29 байт).

0]40X*,1&xDQ0]|S3B{:b^374:B@m
0]40X*                           Prepare a tape with 40 cells
      ,1&                        Assign 1 to the cells specified by the input
         xD                      Repeat the rest of the program 40 times
           Q                     Output current tape
            0]|S                 Prepend and append a 0 cell to it
                3B               All runs of length 3
                  {         m    Map each run with block
                   :b            Convert from binary
                     ^           Increment (call this value `n`)
                      374:B      The binary representation of 374
                                 [1,0,1,1,1,0,1,1,0]
                                 which is `01101110` reversed and prepended a 1
                           @     Element at 0-based index `n`
Вейцзюнь Чжоу
источник
1

K (нгн / к) , 44 35 байт

{"X "39{(2\145)@2/'3'1,x,1}\^x?!40}

Попробуйте онлайн!

{ } функция с аргументом x

!40 список целых от 0 до 39

x?найти их индексы x, используйте 0N("целое число ноль") для не найден

^какие из них нулевые? это дает нам вход, отрицается

39{ }\ применить 39 раз, собирая промежуточные результаты в списке

1,x,1 окружить список 1 (отрицается 0)

3' тройки последовательных предметов

2/' двоичное декодирование каждого

@ использовать в качестве индексов в ...

2\145 двоичное кодирование 145 (отрицательные биты 110)

"X "наконец, используйте матрицу 40x40 в качестве индексов в строке "X "( @здесь подразумевается)

СПП
источник