Zaimplementuj dziwny automat


11

Bawiłem się automatem komórkowym i znalazłem taki, który miał ciekawe zachowanie. Oto jak to działa:

Odczytuje ciąg binarny od lewej do prawej, jeśli napotka 1po nim 2kolejne wartości, dopisze a 0do wyniku i będzie kontynuował czytanie. Jeśli napotka a 0(lub pozostały mniej niż 3 wartości), doda aktualną wartość i a 1i będzie kontynuował czytanie. Na końcu ciągu dołączy 1wynik do pojedynczego .

Oto wypracowany przykład jednego pokolenia

01011111
^

Najpierw napotykamy 0tak, więc dołączamy 01do naszego wyniku

01011111
 ^
01

Teraz napotykamy a, 1więc dodajemy zero i pomijamy kolejne dwie wartości

01011111
    ^
010

Spotykamy innego, 1więc robimy to samo

01011111
       ^
0100

Mamy teraz inną, 1ale niewystarczającą przestrzeń do skoku, więc dołączamy bieżącą komórkę i 1(w tym przypadku 11)

01011111
        ^
010011

Jesteśmy na końcu, więc dołączamy singiel 1i kończymy tę generację

01011111
        ^
0100111

Zadanie

Biorąc pod uwagę dane wejściowe w dowolnym rozsądnym formacie, musisz utworzyć funkcję lub program, który oblicza jedną generację automatu.

To jest pytanie w więc odpowiedzi będą oceniane w bajtach, przy czym mniej bajtów będzie lepszych.

Przykładowa implementacja

Oto przykładowa implementacja w Haskell (definiuje funkcję d, ale program drukuje iteracje w nieskończoność):

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

Wypróbuj online!


W swoim pytaniu stwierdzasz, że mamy teraz jeszcze 1, ale za mało miejsca do skoku, więc dodajemy bieżącą komórkę i 1 lub 11 . Czy to 1 czy 11?
caird coinheringaahing

2
Więc jeśli mamy, 10to powinien wydrukować 11011? Myślę, że przydałoby się jeszcze kilka przypadków testowych
nmjcman101

2
@WheatWizard Doceniłbym jaśniejsze wyjaśnienie, być może tabelę zasad
Aleksander - Przywróć Monikę

2
Nie wierzę, że tak naprawdę jest to automat komórkowy, ale śmiało oświeć mnie definicją mówiącą, że tak.
feersum

2
@feersum Rzeczywiście, nie zachowuje liczby komórek. To przetwornik stanu skończonego .
Ørjan Johansen

Odpowiedzi:


5

V , 26 22 21 bajtów

Dzięki @CowsQuack za 4 bajty, łącząc wyrażenia regularne! I @ ØrjanJohansen dla innego bajtu z niektórymi kombinacjami wyrażeń regularnych.

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

Wypróbuj online!

Używa podstawienia wiele razy i dodaje 1 na końcu. Nic nadzwyczajnego. Mam wersję remaps 1oraz 0w trybie wstawiania, aby uzyskać pożądany efekt, ale jest to trochę dłużej.

(Wiele wersji zastępczych: Wypróbuj online! )


Drugie i trzecie Ó1ü0/&1ü\|
wyrażenie regularne

Geniusz Cowsquack!
nmjcman101

To nawet krótsze nie Ó./&1następuje Ó31/0.
Ørjan Johansen

3

JavaScript (ES6), 56 bajtów

Pobiera dane wejściowe jako tablicę znaków. Zwraca ciąg lub liczbę, 1jeśli podano pustą tablicę.

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

Próbny

Wersja animowana

Przykłady stabilnych danych wejściowych: 0101, 010011111



2

Python 2 , 89 bajtów

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]

Wypróbuj online!

-4 bajty dzięki Rod
-6 bajtów dzięki ovs
-1 bajt dzięki micsthepick


[0]if v else[x[y],1]można przepisać jako [[x[y],1],[0]][v], ale można odwrócić vwartość, aby osiągnąć 96 bajtów
Rod


Nawiasy nie są potrzebne dla instrukcji print w pythonie 2, więc możesz zapisać jeden bajt
micsthepick

2

Swift 3 , 147 bajtów

-1 dzięki @ 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])}

Niegolfowane, zwracanie wartości zamiast drukowania:

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
Można wymienić 3<=s.countz 2<s.countna -1 bajtów .
Pan Xcoder,

@ Mr.Xcoder Thanks! Mogę również wykryć 1s na wejściu 0 < elementzamiast zamiastelement == 0
Alexander - Przywróć Monikę

1

Python 2 , 81 bajtów

Zarówno dane wejściowe, jak i wyjściowe są listami (dzięki Erik the Outgolfer)

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]

Wypróbuj online!

Niektóre przypadki

[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 bajtów

Zarówno wejście, jak i wyjście są ciągami (rozwiązanie początkowe)

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'

Wypróbuj online!

Niektóre przypadki

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

Wyjaśnienie Jest simplily golf metody rekurencyjnej.



@EriktheOutgolfer dzięki :)
mdahmoune

Och, i możesz to zrobić 1>Z[0]zamiast 0==Z[0].
Erik the Outgolfer


0

Scala , 131 + 29 = 160 bajtów

Jest to funkcja, która przyjmuje ciąg ajako parametr i zwraca dane wyjściowe jako ciąg.

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"

Muszę to zrobić import util.control.Breaks._, więc muszę dodać te 28 bajtów plus końcowy kanał.

Wypróbuj online!


0

C # (.NET Core) , 108 bajtów

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";}

Wypróbuj online!

Dane wejściowe są traktowane jako ciąg, a ciąg jest zwracany jako wynik.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.