Changer les règles de la vie

15

L'automate cellulaire semblable à la vie est un automate cellulaire qui est similaire au Game of Life de Conway, en ce sens qu'il fonctionne sur une grille carrée (théoriquement) infiniment grande, où chaque cellule a exactement 8 voisins et est l'un des 2 états, à savoir vivant et mort. .

Cependant, ces versions similaires sont différentes de manière cruciale: les règles pour qu'une cellule donnée prenne vie et les règles pour une cellule donnée pour survivre à la prochaine génération.

Par exemple, Game of Life classique utilise la règle B3/S23, ce qui signifie qu'il faut 3 cellules vivantes pour en créer une nouvelle et 2 ou 3 voisins vivants pour survivre. Pour ce défi, nous supposerons que les voisins ne s’incluent pas, donc chaque cellule a exactement 8 voisins.

Votre tâche est, étant donné une configuration de départ, une règle de naissance, une règle de survie et un entier positif (le nombre de générations à exécuter), simuler l'automate Life-like en utilisant ces règles pour le nombre de générations donné dans le code le plus court possible . La configuration de départ sera une matrice carrée / un tableau bidimensionnel ou une chaîne multiligne, vous pouvez choisir. Les autres peuvent être donnés dans n'importe quel format et méthode raisonnables.

Par exemple, si la règle de naissance était 12345678(tout voisin vivant), la règle de survie l'était 2357et la configuration de départ était

0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0

les deux prochaines générations seraient

Generation 1:           Generation 2:

0 0 0 0 0               1 1 1 1 1
0 1 1 1 0               1 1 0 1 1
0 1 0 1 0               1 0 1 0 1
0 1 1 1 0               1 1 0 1 1
0 0 0 0 0               1 1 1 1 1

Si le nombre de générations donné était de 10, la sortie serait quelque chose dans le sens de

0 1 1 1 0
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 1 1 1 0

Vous n'avez pas à gérer les modifications qui se produisent en dehors des limites données par la matrice d'entrée, cependant, toutes les cellules en dehors de la matrice commencent mortes. Par conséquent, la matrice d'entrée peut être de n'importe quelle taille, jusqu'à la valeur maximale que votre langue peut prendre en charge. Vous n'avez pas besoin de sortir la carte entre les générations.

Ceci est un donc le code le plus court l'emporte.

Cas de test

Ceux-ci utilisent la B/Snotation pour indiquer les règles utilisées

B2/S2, generations = 100, Configuration:

1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0

Production:

0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 0
1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

B1357/S2468, generations = 12, Configuration:

1 0 1 0 1 0
0 1 1 0 1 0
1 0 0 0 0 0
0 0 0 0 0 1
1 1 1 1 1 0
0 1 1 0 0 1

Production:

0 1 0 0 0 0
0 1 1 1 1 0
0 1 0 1 1 0
1 1 1 0 0 0
0 0 1 1 1 0
0 1 1 0 0 0

Si vous avez besoin de générer plus de cas de test, vous pouvez utiliser ce merveilleux simulateur. Veuillez vous assurer de limiter la taille de la planche

caird coinheringaahing
la source
La simulation est-elle toroïdale?
Erik the Outgolfer
@EriktheOutgolfer no, car la matrice est (théoriquement) de taille infinie
caird coinheringaahing
Peut-on également supposer que la matrice donnée est carrée?
Erik the Outgolfer
2
@EriktheOutgolfer "grille carrée infiniment grande"
caird coinheringaahing
Mais cela ne dit pas que vous pouvez supposer que ... sera édité.
Erik the Outgolfer

Réponses:

9

MATL , 24 23 octets

xx:"tt3Y6Z+1Gm<8M2Gmb*+

Les entrées sont:

  • Tableau avec règle de naissance
  • Tableau avec règle de survie
  • Nombre de générations
  • Matrice avec configuration initiale des cellules, utilisant ;comme séparateur de lignes.

Essayez-le en ligne! Ou voir les cas de test: 1 , 2 .

Pour quelques octets de plus, vous pouvez voir l' évolution de l'art ASCII .

Explication

xx      % Take two inputs implicitly: birth and survival rules. Delete them
        % (but they get copied into clipboard G)
:"      % Take third input implicitly: number of generations. Loop that many times
  tt    %   Duplicate twice. This implicitly takes the initial cell configuration
        %   as input the first time. In subsequent iterations it uses the cell 
        %   configuration from the previous iteration
  3Y6   %   Push Moore neighbourhood: [1 1 1; 1 0 1; 1 1 1]
  Z+    %   2D convolution, maintaining size
  1G    %   Push first input from clipboard G: birth rule
  m     %   Ismember: gives true for cells that fulfill the birth rule
  <     %   Less than (element-wise): a cell is born if it fulfills the birth rule
        %   *and* was dead
  8M    %   Push result of convolution again, from clipboard M
  2G    %   Push second input from clipboard G: survival rule
  m     %   Ismember: gives true for cells that fulfill the survival rule
  b     %   Bubble up the starting cell configuration
  *     %   Multiply (element-wise): a cell survives if it fulfills the survival
        %   rule *and* was alive
  +     %   Add: a cell is alive if it has been born or has survived, and those
        %   are exclusive cases. This produces the new cell configuration
        % Implicit end loop. Implicit display
Luis Mendo
la source
Pouvez-vous économiser des octets en modifiant l'ordre des entrées? Le xxdébut me semble un peu gaspilleur ...
Erik the Outgolfer
@EriktheOutgolfer Je ne vois pas comment. Je dois supprimer les deux premiers pour les réutiliser plus tard plusieurs fois (une par itération), et les autres entrées sont déjà implicites maintenant
Luis Mendo
Oh donc "supprimer" les entrées les ajoute à une sorte de liste d'entrées?
Erik the Outgolfer
@EriktheOutgolfer Oui. L'entrée MATL est interactive, ce qui signifie que le programme ne sait pas à l'avance combien d'entrées il y a. Ici, la suppression d'une pile vide entraîne la prise implicite d'une entrée. Une fois prise, chaque entrée est copiée dans le presse-papiers G et peut être récupérée plus tard.
Luis Mendo
3

Wolfram Language (Mathematica) , 144 122 octets

CellularAutomaton[{Tr[2^#&/@Flatten@MapIndexed[2#+2-#2[[1]]&,{#2,#3},{2}]],{2,{{2,2,2},{2,1,2},{2,2,2}}},{1,1}},#,{{#4}}]&

Essayez-le en ligne!

Exemple d'utilisation:

%[RandomInteger[1, {10, 10}], {2, 3}, {3}, 5]

utilise une grille aléatoire 10x10 comme point de départ, survit avec 2 ou 3 voisins, naissances avec 3 voisins, résultat du tracé à 5 itérations.

Kelly Lowder
la source
Dommage que le builtin ne soit qu'une dimension (corrigez-moi si je me trompe)
Zacharý
J'utilise le "CellularAutomaton" intégré avec une règle totaliste à 9 voisins. Une grande partie du code convertit les entrées de survie / naissance en un numéro de règle.
Kelly Lowder
1

R , 256 octets

function(x,B,S,r){y=cbind(0,rbind(0,x,0),0)
n=dim(y)[1]
z=c(1,n)
f=function(h){w=-1:1
b=h%%n+1
a=(h-b+1)/n+1
'if'(a%in%z|b%in%z,0,sum(x[w+b,w+a])-x[b,a])}
while(r){x=y
for(i in 1:n^2){u=f(i-1)
y[i]=u%in%B
y[i]=(y[i]&!x[i])|(x[i]&(u%in%S))}
r=r-1}
y[-z,-z]}

Essayez-le en ligne!

Malheureusement, cela ne semble pas aussi golfé que je l'espérais.

Entrée : une matrice R et les paramètres du défi. Sortie : la matrice après R générations.

L'algorithme remplit la matrice de zéros pour gérer les limites. Ensuite, de manière itérative: 1er) il applique la règle de naissance et 2) il tue les cellules préexistantes qui n'ont pas passé la règle de survie. Le rembourrage est retiré lors du retour.

NofP
la source
compte d'octets sympa!
Giuseppe
J'ai réussi à l'amener à 217 octets mais si nous pouvons trouver exactement un golf de plus, nous pouvons y arriver 216qui est au moins un cube ...
Giuseppe
1

Python 2 , 156 149 146 146 octets

lambda R,g,c:g and f(R,g-1,[[`sum(sum(l[y+y/~y:y+2])for l in c[x+x/~x:x+2])-c[x][y]`in R[c[x][y]]for y,_ in e(c)]for x,_ in e(c)])or c
e=enumerate

Essayez-le en ligne!

Prend entrée:

  • Rules: [birth,survial]règles comme liste de string. par exemple. ( ['135','246'])
  • générations: int
  • configuration: tableau 2D carré de 1/0ouTrue/False

Renvoie un tableau 2D de True/False

TFeld
la source