Implémenter un étrange automate

11

Je jouais avec un automate cellulaire et j'en ai trouvé un qui avait un comportement intéressant. Voici comment ça fonctionne:

Il lit une chaîne binaire de gauche à droite, s'il rencontre un 1suivi par d' 2autres valeurs, il ajoutera un 0au résultat et continuera la lecture. S'il rencontre a 0(ou s'il reste moins de 3 valeurs), il ajoutera la valeur actuelle et a 1et continuera la lecture. À la fin de la chaîne, il en ajoutera un simple 1au résultat.

Voici un exemple élaboré d'une génération

01011111
^

Nous rencontrons d'abord un 0donc nous ajoutons 01à notre résultat

01011111
 ^
01

Maintenant, nous rencontrons un 1donc nous ajoutons un zéro et sautons les deux valeurs suivantes

01011111
    ^
010

On en rencontre un autre 1donc on fait de même

01011111
       ^
0100

Nous avons maintenant un autre 1espace mais pas assez pour sauter, donc nous ajoutons la cellule actuelle et un 1(dans ce cas 11)

01011111
        ^
010011

Nous sommes à la fin donc nous ajoutons un single 1et terminons cette génération

01011111
        ^
0100111

Tâche

Étant donné l'entrée dans un format raisonnable, vous devez créer une fonction ou un programme qui calcule une génération de l'automate.

Il s'agit d'une question de donc les réponses seront notées en octets, avec moins d'octets étant mieux.

Exemple d'implémentation

Voici un exemple d'implémentation dans Haskell (définit une fonction d, mais le programme imprime indéfiniment une itération):

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

Essayez-le en ligne!

Ad Hoc Garf Hunter
la source
Dans votre question, vous déclarez Nous avons maintenant un autre 1 mais pas assez d'espace pour sauter, donc nous ajoutons la cellule actuelle et un 1 ou 11 . Est-ce 1 ou 11?
caird coinheringaahing
2
Alors, si nous en avons un, 10il devrait s'imprimer 11011? Je pense que quelques cas de test supplémentaires seraient utiles
nmjcman101
2
@WheatWizard J'apprécierais une explication plus claire, peut-être un tableau, des règles
Alexander - Reinstate Monica
2
Je ne crois pas que ce soit en fait un automate cellulaire, mais n'hésitez pas à m'éclairer avec une définition disant que c'est le cas.
feersum
2
@feersum En effet, il ne conserve pas le nombre de cellules. C'est un transducteur à états finis .
Ørjan Johansen

Réponses:

5

V , 26 22 21 octets

Merci à @CowsQuack pour 4 octets en combinant des expressions régulières! Et @ ØrjanJohansen pour un autre octet avec quelques combinaisons d'expression régulière.

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

Essayez-le en ligne!

Utilise plusieurs fois le substitut et ajoute un 1 à la fin. Rien d'extraordinaire. J'ai une version qui remappe 1et 0en mode insertion pour obtenir l'effet désiré, mais c'est un peu plus long.

(Version de remplacement multiple: essayez-le en ligne! )

nmjcman101
la source
Les deuxième et troisième expressions régulières peuvent fusionner en Ó1ü0/&1( üest \|)
user41805
@Cowsquack genius!
nmjcman101
C'est encore plus court à faire Ó./&1suivi de Ó31/0.
Ørjan Johansen
3

JavaScript (ES6), 56 octets

Prend l'entrée comme un tableau de caractères. Renvoie une chaîne ou le nombre 1si un tableau vide est fourni.

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

Démo

Version animée

Exemples d'entrées stables: 0101, 010011111

Arnauld
la source
2

Python 2 , 89 octets

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]

Essayez-le en ligne!

-4 octets grâce à Rod
-6 octets grâce à ovs
-1 octet grâce à micsthepick

HyperNeutrino
la source
[0]if v else[x[y],1]peut être réécrit comme [[x[y],1],[0]][v], mais vous pouvez inverser la vvaleur pour atteindre 96 octets
Rod
90 octets
ovs
Les parenthèses ne sont pas nécessaires pour l'instruction print en python 2, vous pouvez donc enregistrer un octet
micsthepick
2

Swift 3 , 147 octets

-1 merci à @ 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])}

Non golfé, renvoyant la valeur plutôt que l'impression:

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 - Rétablir Monica
la source
1
Vous pouvez remplacer 3<=s.countpar 2<s.countpour -1 octets .
M. Xcoder
@ Mr.Xcoder Merci! Je peux également détecter des 1s dans l'entrée avec 0 < elementplutôt queelement == 0
Alexander - Reinstate Monica
1

Python 2 , 81 octets

L'entrée et la sortie sont des listes (grâce à Erik l'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]

Essayez-le en ligne!

Certains cas

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

L'entrée et la sortie sont des chaînes (solution initiale)

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'

Essayez-le en ligne!

Certains cas

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

Explication Il s'agit simplement d'un golf d'une méthode récursive.

mdahmoune
la source
L'utilisation des listes est plus courte.
Erik le Outgolfer
@EriktheOutgolfer merci :)
mdahmoune
Oh, et vous pouvez faire à la 1>Z[0]place de 0==Z[0].
Erik the Outgolfer
0

Scala , 131 + 29 = 160 octets

C'est à l'intérieur d'une fonction prenant la chaîne aen paramètre et retournant la sortie sous forme de chaîne.

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"

Je dois import util.control.Breaks._ , j'ai donc besoin d'ajouter ces 28 octets plus un saut de ligne de fin.

Essayez-le en ligne!

V. Courtois
la source
0

C # (.NET Core) , 108 octets

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

Essayez-le en ligne!

Entrée prise sous forme de chaîne et une chaîne est renvoyée en sortie.

jkelm
la source