Implementiere einen seltsamen Automaten

11

Ich habe mit dem Mobilfunkautomaten herumgespielt und einen gefunden, der ein interessantes Verhalten hatte. So funktioniert das:

Es liest eine Binärzeichenfolge von links nach rechts. Wenn es auf einen Wert 1gefolgt von 2anderen Werten stößt , wird ein a 0an das Ergebnis angehängt und das Lesen fortgesetzt. Wenn es auf a trifft 0(oder weniger als 3 Werte übrig sind), wird der aktuelle Wert und a angehängt 1und das Lesen fortgesetzt. Am Ende der Zeichenfolge wird eine einzelne 1an das Ergebnis angehängt .

Hier ist ein ausgearbeitetes Beispiel einer Generation

01011111
^

Wir begegnen zuerst einem, 0also hängen wir 01an unser Ergebnis

01011111
 ^
01

Jetzt begegnen wir einer, 1also fügen wir eine Null hinzu und überspringen die nächsten beiden Werte

01011111
    ^
010

Wir begegnen einem anderen, 1also tun wir dasselbe

01011111
       ^
0100

Wir haben jetzt einen anderen, 1aber nicht genügend Platz zum Springen, sodass wir die aktuelle Zelle und ein 1(in diesem Fall 11) anhängen.

01011111
        ^
010011

Wir sind am Ende, also fügen wir eine Single hinzu 1und beenden diese Generation

01011111
        ^
0100111

Aufgabe

Bei Eingabe in einem vernünftigen Format müssen Sie eine Funktion oder ein Programm erstellen, das eine Generation des Automaten berechnet.

Dies ist eine Frage, daher werden die Antworten in Bytes bewertet, wobei weniger Bytes besser sind.

Beispielimplementierung

Hier ist eine Beispielimplementierung in Haskell (definiert eine Funktion d, aber das Programm druckt eine Iteration auf unbestimmte Zeit):

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

Probieren Sie es online aus!

Post Rock Garf Hunter
quelle
In Ihrer Frage geben Sie an, dass wir jetzt eine weitere 1 haben, aber nicht genug Platz zum Springen, sodass wir die aktuelle Zelle und eine 1 oder 11 anhängen . Ist es 1 oder 11?
Caird Coinheringaahing
2
Also, wenn wir eine haben 10, sollte sie gedruckt werden 11011? Ich denke, ein paar weitere Testfälle wären hilfreich
nmjcman101
2
@ WheatWizard Ich würde mich über eine klarere Erklärung, vielleicht eine Tabelle, der Regeln freuen
Alexander - Reinstate Monica
2
Ich glaube nicht, dass dies tatsächlich ein zellularer Automat ist, aber Sie können mich gerne mit einer Definition aufklären, die besagt, dass dies der Fall ist.
Feersum
2
@feersum In der Tat wird die Anzahl der Zellen nicht beibehalten. Es ist ein Wandler mit endlichem Zustand .
Ørjan Johansen

Antworten:

5

V , 26 22 21 Bytes

Vielen Dank an @CowsQuack für 4 Bytes durch die Kombination von Regexen! Und @ ØrjanJohansen für ein weiteres Byte mit einigen Regex-Kombinationen.

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

Probieren Sie es online aus!

Verwendet den Ersatz mehrmals und fügt am Ende eine 1 hinzu. Nichts Besonderes. Ich habe eine Version, die neu zugeordnet 1und 0im Einfügemodus ist, um den gewünschten Effekt zu erzielen, aber sie ist ziemlich viel länger.

(Mehrfachersatzversion: Probieren Sie es online aus! )

nmjcman101
quelle
Die zweite und dritte Regex können in Ó1ü0/&1( üis \|)
user41805
@Cowsquack Genie!
nmjcman101
Es ist noch kürzer, Ó./&1gefolgt von Ó31/0.
Ørjan Johansen
3

JavaScript (ES6), 56 Byte

Nimmt die Eingabe als Array von Zeichen auf. Gibt eine Zeichenfolge oder die Zahl zurück, 1wenn ein leeres Array angegeben ist.

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

Demo

Animierte Version

Beispiele für stabile Eingänge: 0101, 010011111

Arnauld
quelle
2

Python 2 , 89 Bytes

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]

Probieren Sie es online aus!

-4 Bytes dank Rod
-6 Bytes dank OVs
-1 Bytes dank Micsthepick

HyperNeutrino
quelle
[0]if v else[x[y],1]kann umgeschrieben werden als [[x[y],1],[0]][v], aber Sie können den vWert invertieren , um 96 Bytes
Rod
90 Bytes
ovs
Klammern werden für die
Druckanweisung
2

Swift 3 , 147 Bytes

-1 danke an @ 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, gibt den Wert zurück, anstatt zu drucken:

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]
}
Alexander - Monica wieder einsetzen
quelle
1
Sie können ersetzen 3<=s.countmit 2<s.countfür -1 Bytes .
Herr Xcoder
@ Mr.Xcoder Danke! Ich kann auch 1s in der Eingabe mit 0 < elementanstattelement == 0
Alexander - Reinstate Monica
1

Python 2 , 81 Bytes

Sowohl Eingabe als auch Ausgabe sind Listen (danke an Erik den 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]

Probieren Sie es online aus!

Manche Fälle

[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 Bytes

Sowohl Eingabe als auch Ausgabe sind Zeichenfolgen (anfängliche Lösung)

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'

Probieren Sie es online aus!

Manche Fälle

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

Erklärung Es ist einfach ein Golf einer rekursiven Methode.

mdahmoune
quelle
Die Verwendung von Listen ist kürzer.
Erik der Outgolfer
@EriktheOutgolfer danke :)
mdahmoune
Oh, und du kannst es 1>Z[0]stattdessen tun 0==Z[0].
Erik der Outgolfer
0

Scala , 131 + 29 = 160 Bytes

Dies befindet sich in einer Funktion, die die Zeichenfolge aals Parameter verwendet und die Ausgabe als Zeichenfolge zurückgibt.

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"

Ich muss import util.control.Breaks._, also muss ich diese 28 Bytes plus einen nachgestellten Zeilenvorschub hinzufügen.

Probieren Sie es online aus!

V. Courtois
quelle
0

C # (.NET Core) , 108 Byte

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

Probieren Sie es online aus!

Die Eingabe wird als Zeichenfolge verwendet, und eine Zeichenfolge wird als Ausgabe zurückgegeben.

jkelm
quelle