Реализуйте странный автомат

11

Я играл с клеточным автоматом и нашел тот, у которого было интересное поведение. Вот как это работает:

Он читает двоичную строку слева направо, если он встречает другое, а 1затем 2другие значения, он добавляет 0к результату и продолжает чтение. Если он встретит a 0(или осталось менее 3 значений), он добавит текущее значение и a 1и продолжит чтение. В конце строки он добавит один 1к результату.

Вот отработанный пример одного поколения

01011111
^

Сначала мы сталкиваемся с 0таким, мы добавляем 01к нашему результату

01011111
 ^
01

Теперь мы сталкиваемся с 1таким образом, мы добавляем ноль и пропускаем следующие два значения

01011111
    ^
010

Мы сталкиваемся с другим, 1поэтому мы делаем то же самое

01011111
       ^
0100

Теперь у нас есть другое, 1но недостаточно места для прыжка, поэтому мы добавляем текущую ячейку и a 1(в данном случае 11)

01011111
        ^
010011

Мы в конце, поэтому мы добавляем сингл 1и прекращаем это поколение

01011111
        ^
0100111

задача

Учитывая ввод в любом разумном формате, вы должны создать функцию или программу, которая вычисляет одно поколение автомата.

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

Пример реализации

Вот пример реализации в Haskell (определяет функцию d, но программа печатает итерации бесконечно):

d('1':_:_:x) = "0" ++ d x
d(a:x) = a:'1':d x
d x = "1"
r x = x:map d(r x)

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

Специальный охотник за гарфами
источник
В своем вопросе вы утверждаете, что у нас теперь есть еще 1, но недостаточно места для прыжка, поэтому мы добавляем текущую ячейку и 1 или 11 . Это 1 или 11?
Caird Coneheringaahing
2
Так тогда, если у нас есть, 10это должно напечатать 11011? Я думаю, что было бы полезно еще несколько тестов
nmjcman101
2
@WheatWizard Я был бы признателен за более четкое объяснение, возможно, за столом, правил
Александр - Восстановить Монику
2
Я не верю, что это на самом деле клеточный автомат, но не стесняйтесь просветить меня определением, говорящим, что это так.
feersum
2
@feersum Действительно, это не сохраняет количество ячеек. Это конечный датчик .
Орджан Йохансен,

Ответы:

5

V , 26 22 21 байт

Спасибо @CowsQuack за 4 байта за счет объединения регулярных выражений! И @ ØrjanJohansen для другого байта с некоторыми комбинациями регулярных выражений.

Ó1../3
Ó./&1
Ó31/0
A1

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

Использует замену несколько раз и добавляет 1 в конце. Ничего особенного. У меня есть версия, которая переназначается 1и 0в режиме вставки, чтобы получить желаемый эффект, но это немного дольше.

(Несколько вариантов замены: попробуйте онлайн! )

nmjcman101
источник
Второе и третье регулярные выражения могут объединиться в Ó1ü0/&1( üесть \|)
user41805
@ Гениальный гангстер!
nmjcman101
Это еще короче, Ó./&1а затем Ó31/0.
Орджан Йохансен,
3

JavaScript (ES6), 56 байт

Принимает ввод как массив символов. Возвращает строку или число, 1если дан пустой массив.

f=([v,...a])=>v?(+v&&a[1]?a.splice(0,2)&&'0':v+1)+f(a):1

демонстрация

Анимированная версия

Примеры стабильных входов: 0101, 010011111

Arnauld
источник
2

Python 2 , 89 байт

x=input()
y=0
k=[]
while x[y:]:v=1-x[y]*(y<len(x)-2);k+=[x[y]]*v+[v];y+=3-2*v
print k+[1]

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

-4 байта благодаря Rod
-6 байтов благодаря ovs
-1 байту благодаря micsthepick

HyperNeutrino
источник
[0]if v else[x[y],1]можно переписать как [[x[y],1],[0]][v], но вы можете инвертировать vзначение, чтобы достичь 96 байт
Род
90 байт
овс
Круглые скобки не нужны для оператора print в python 2, поэтому вы можете сохранить один байт
micsthepick
2

Swift 3 , 147 байт

-1 благодаря @ Mr.Xcoder

func g(i:[Int]){var r=[Int]();var s=ArraySlice(i);while let e=s.popFirst(){if 0<e&&2<s.count{r+=[0];s=s.dropFirst(2)}else{r+=[e,1]}};print(r+[1])}

Разгруженный, возвращающий значение вместо печати:

func iterate(state: [Int]) -> [Int] {
    var result = [Int]()

    var inputSlice = ArraySlice(state)

    while let element = inputSlice.popFirst() {
        if 0 < element && 2 < inputSlice.count { 
            result += [0]
            inputSlice = inputSlice.dropFirst(2)
        }
        else {
            result += [element, 1]
        }

        //debugPrint(result.map(String.init).joined(separator: ""))
    }

    return result + [1]
}
Александр - Восстановить Монику
источник
1
Вы можете заменить 3<=s.countс 2<s.countна -1 байт .
Мистер Кскодер
@ Mr.Xcoder Спасибо! Я также могу обнаружить 1s на входе, 0 < elementа неelement == 0
Александр - Восстановить Монику
1

Python 2 , 81 байт

И вход, и выход являются списками (спасибо Эрику Гольфисту)

def f(Z):return Z and((1>Z[0]or 3>len(Z))and[Z[0],1]+f(Z[1:])or[0]+f(Z[3:]))or[1]

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

Некоторые случаи

[0,1,0,1,1,1,1,1] --> [0,1,0,0,1,1,1]
[0] ----------------> [0,1,1]
[1] ----------------> [1,1,1]
[] -----------------> [1]
[0,1] --------------> [0,1,1,1,1]
[1,0] --------------> [1,1,0,1,1]

Python 2 , 85 байт

И вход, и выход являются строками (исходное решение)

def f(Z):return Z and(('0'==Z[0]or 3>len(Z))and Z[0]+'1'+f(Z[1:])or'0'+f(Z[3:]))or'1'

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

Некоторые случаи

'01011111'--> 0100111
'0'---------> 011
'1'---------> 111
''----------> 1
'01'--------> 01111
'10'--------> 11011

Экспликация Это просто гольф рекурсивного метода.

mdahmoune
источник
Использование списков короче.
Эрик Outgolfer
@EriktheOutgolfer спасибо :)
mdahmoune
Ох, и вы можете сделать 1>Z[0]вместо 0==Z[0].
Эрик Outgolfer
0

Scala , 131 + 29 = 160 байт

Это внутри функции, принимающей строку в aкачестве параметра и возвращающей вывод в виде строки.

var s=""
var k=0
for(c<-0 to a.length-1)breakable{if(k>0){k-=1
break}
if(a(c)==49&c<a.length-3){s+="0"
k+=2}else s+=a(c)+"1"}
s+"1"

Я должен import util.control.Breaks._, поэтому мне нужно добавить эти 28 байтов плюс завершающий перевод строки.

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

В. Куртуа
источник
0

C # (.NET Core) , 108 байт

n=>{var t="";for(int i=0,b=n.Length;i<b;){if(n[i]>'0'&i+2<b){t+="0";i+=3;}else t+=n[i++]+"1";}return t+"1";}

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

Ввод принимается как строка, а строка возвращается в качестве вывода.

jkelm
источник