Реалізуйте дивний автомат


11

Я бавився зі стільниковим автоматом, і виявив той, який мав цікаву поведінку. Ось як це працює:

Він читає двійковий рядок зліва направо, якщо він зустрічається з 1наступними 2іншими значеннями, він додає a 0до результату і продовжить читання. Якщо він зіткнеться з 0(або залишилося менше 3 значень), він додасть поточне значення а 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 coinheringaahing

2
Тож якщо ми маємо 10його, слід надрукувати 11011? Я думаю, що ще кілька тестових випадків будуть корисними
nmjcman101

2
@WheatWizard Я би вдячний за більш чітке пояснення, можливо, таблиці, правил
Олександр - Відновити Моніку

2
Я не вірю, що це насправді стільниковий автомат, але не соромтеся просвітлити мене визначенням, яке говорить про це.
feersum

2
@feersum Дійсно, він не зберігає кількість комірок. Це перетворювач кінцевого стану .
Ørjan Johansen

Відповіді:


5

V , 26 22 21 байт

Завдяки @CowsQuack за 4 байти, поєднуючи регулярні вирази! І @ ØrjanJohansen - ще один байт з кількома комбінаціями регулярних виразів.

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

Спробуйте в Інтернеті!

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

(Кілька варіантів заміни: Спробуйте в Інтернеті! )


Другий і третій регекси можуть зливатися в Ó1ü0/&1( üє \|)
user41805

@ Геній Коусквака!
nmjcman101

Це ще коротше, Ó./&1за яким слід Ó31/0.
Ørjan Johansen

3

JavaScript (ES6), 56 байт

Вводить дані як масив символів. Повертає рядок або число, 1якщо дано порожній масив.

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

Демо

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

Приклади стабільних входів: 0101, 010011111



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 байти завдяки Род
-6 байтів, завдяки ovs
-1 байту завдяки micsthepick


[0]if v else[x[y],1]можна переписати як [[x[y],1],[0]][v], але ви можете перевернути vзначення, щоб досягти 96 байт
стрижень


Дужки не потрібні для оператора друку в python 2, тому ви можете зберегти один байт
micsthepick

2

Швидкий 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])}

Ungolfed, повертаючи значення, а не друкуючи:

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 байт .
Містер Xcoder

@ 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

Пояснення Це просто гольф рекурсивного методу.



@EriktheOutgolfer дякую :)
mdahmoune

О, і ви можете зробити 1>Z[0]замість цього 0==Z[0].
Ерік Аутгольфер


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 байт плюс кінцевий рядковий канал.

Спробуйте в Інтернеті!


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