Implémentez le jeu de la vie en 3D

17

Le défi est de trouver la mise en œuvre la plus courte du jeu de la vie en 3D ( exemple ). Ce sont les règles:

Les cellules (dans ce cas, les cubes) avec seulement 1 voisin ou moins meurent, comme par solitude.
Si exactement 5 cellules entourent une cellule vide, elles se reproduisent et la remplissent.
Si une cellule a 8 voisins ou plus, elle meurt du surpeuplement.

Faites-en au moins un 10x10x10, où les couches sont sorties individuellement comme ceci:

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 X 0 0 X 0 0 0 0 0
0 0 X X X 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 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Bien sûr, une simulation graphique 3D est également acceptée.
La position de départ peut être codée en dur mais elle doit fonctionner si elle est changée en n'importe quelle position de départ. Il doit être capable de calculer n'importe quel nombre de générations et l'utilisateur doit pouvoir demander manuellement la génération suivante.

Le code le plus court en caractères gagne!

J'ai fait ma propre implémentation de ceci pour n'importe quelle taille (cube): http://jensrenders.site88.net/life3D.htm Vous pouvez l'utiliser pour tester, et vous pouvez baser votre code sur le mien, bien que je ne l'aie pas commenté .

Jens Renders
la source
1
Impliqué la balise code-golf de votre déclaration trouve l'implémentation la plus courte . Veuillez vérifier si c'est ce que vous voulez. Vous devez également donner quelques détails sur la façon de saisir, le nombre de cycles, les oui / non animés, ... car il est essentiel que le code-golf ait une spécification robuste.
Howard
@Howard J'ai ajouté quelques spécifications supplémentaires, et oui, j'ai oublié la balise code-golf;) merci pour cela.
Jens Renders
@PeterTaylor Oui exactement 5, je vais le modifier.
Jens Renders
J'ajouterais des détails sur le format de sortie (par exemple, chaque cellule doit être séparée par un espace comme dans votre exemple, une nouvelle ligne entre chaque couche de grille de la sortie, les cellules vivantes et mortes doivent être représentées par des caractères différents, et celles-ci doivent être des caractères visibles .) Gardez également à l'esprit que si vous êtes encadré comme du code-golf, il est peu probable que vous obteniez des simulations graphiques.
Jonathan Van Matre
Vouliez-vous vraiment interdire toutes les échappatoires discutées dans ce méta-fil, ou seulement celles répondant aux critères de (dés) approbation (score +5, au moins deux fois plus de votes positifs que de votes négatifs)? Parce que je suis sûr que je pourrais totalement penser à des "failles" assez intéressantes à discuter ... ;-)
Ilmari Karonen

Réponses:

14

Mathematica - 120 octets

g=CellularAutomaton[{(l=Flatten@#;c=l[[14]];n=Total@Drop[l,{14}];Which[n<2||n>7,0,n==5||c==1,1,0<1,0])&,{},{1,1,1}},##]&

Certainement pas un prétendant à la victoire, mais ce n'était pas mon intention. En outre, cela pourrait probablement être considérablement minimisé en déterminant simplement le numéro de la règle. Je voulais juste vraiment écrire une visualisation (même si je suis sûr qu'il y en a déjà des tonnes). Alors c'est parti):

animateGol3d[size_, i_, n_] := 
  ListAnimate[
    Graphics3D[
      Cuboid /@ Position[#, 1], 
      PlotRange -> {{0, size}, {0, size}, {0, size}} + 1
    ] & /@ g[i, n]
  ];

Et après avoir expérimenté un tas de conditions initiales, j'ai eu des choses comme ceci:

entrez la description de l'image ici

Et voici un avec une taille de grille de 20x20x20. Cela a pris quelques secondes pour simuler et rendre:

entrez la description de l'image ici

Soit dit en passant, cela suppose des conditions aux limites périodiques.

Martin Ender
la source
Ceux-ci entrent-ils vraiment dans un état d'équilibre, ou est-ce simplement l'arrêt de l'animation? Si l'ancien, vous m'avez donné quelques
bonnes
1
@Kroltan Cela fait un moment, mais je suis presque sûr qu'ils atteignaient l'équilibre.
Martin Ender
1
Bien, merci. Les coupes individuelles de l'équilibre semblent par exemple très proches de la pièce, un jeu semblable à un rougel.
Kroltan
12

APL, 46

Cela m'a pris du temps, mais je suis descendu à 46 caractères:

{(5=m)∨⍵∧3>|5.5-m←⊃+/,i∘.⌽i∘.⊖(i←2-⍳3)⌽[2]¨⊂⍵}

Il s'agit d'une fonction qui prend une matrice booléenne 3D de n'importe quelle taille et calcule la prochaine génération, selon les règles données. Les conditions aux limites n'étant pas spécifiées, j'ai donc choisi d'enrouler l'autre côté, comme dans l'espace toroïdal.

Explication

{                           ⊂⍵}   Take the argument matrix and enclose it in a scalar
               (i←2-⍳3)           Prepare an array with values -1 0 1 and call it i
                       ⌽[2]¨      Shift the matrix along the 2nd dim. by each of -1 0 1
           i∘.⊖                   Then for each result do the same along the 1st dimension
       i∘.⌽                       And for each result again along the 3rd dimension
 m←⊃+/,                           Sum element-wise all 27 shifted matrices and call it m

Le résultat intermédiaire mest une matrice de même forme que la matrice d'origine, qui compte pour chaque élément le nombre de cellules vivantes dans son voisinage 3 × 3 × 3, y compris lui-même. Alors:

           |5.5-m   For each element (x) in m, take its distance from 5.5
       ⍵∧3>         If that distance is <3 (which means 3≤x≤8) and the original cell was 1,
 (5=m)∨             or if the element of m is 5, then the next generation cell will be 1.

Exemple

Définissez une matrice aléatoire 4 × 4 × 4 avec environ 1/3 de cellules = 1 et calculez sa 1ère et 2ème génération. Le ⊂[2 3]devant n'est qu'une astuce pour imprimer les avions horizontalement au lieu de verticalement:

      ⊂[2 3] m←1=?4 4 4⍴3
 1 0 0 0  1 0 1 0  1 0 1 0  0 0 0 1 
 1 1 0 0  0 0 0 0  0 0 0 1  1 0 1 0 
 0 0 0 0  0 1 0 0  0 0 0 0  0 0 1 0 
 1 1 0 0  0 0 0 1  1 0 0 1  0 0 1 0 
      ⊂[2 3] {(5=m)∨⍵∧3>|5.5-m←⊃+/,i∘.⌽i∘.⊖(i←2-⍳3)⌽[2]¨⊂⍵} m
 0 0 0 0  0 0 1 0  1 0 1 0  0 0 0 0 
 1 0 0 0  0 0 1 0  0 0 0 0  1 0 1 0 
 0 0 0 0  0 1 0 0  0 0 0 0  0 0 1 0 
 1 1 0 0  0 0 0 0  1 0 0 0  0 0 1 0 
      ⊂[2 3] {(5=m)∨⍵∧3>|5.5-m←⊃+/,i∘.⌽i∘.⊖(i←2-⍳3)⌽[2]¨⊂⍵}⍣2⊢ m
 0 0 1 0  1 0 1 0  1 0 1 0  0 0 0 0 
 1 0 1 0  0 0 1 1  0 0 0 0  1 0 1 0 
 1 0 0 0  1 1 0 0  0 0 1 0  1 0 1 0 
 1 1 1 0  1 0 0 1  1 0 1 0  0 0 1 0 
Tobia
la source
+1 Très belle réponse! et en effet, les limites n'étaient pas spécifiées, donc le bouclage est autorisé.
Jens Renders
9

J - 42 caractères

Nous supposons une planche toroïdale (enroulée autour) dans les trois dimensions. L'affichage automatique des résultats de J semble suivre la spécification de sortie, en utilisant 1pour les cellules vivantes et 0pour les morts. Ce code fonctionne sur des planches de n'importe quelle largeur, longueur et hauteur (peut être 10x10x10, 4x5x6, etc.).

(((1&<*<&8)@-*]+.5=-)~[:+/(,{3#<i:1)|.&><)

Une explication suit:

  • ,{3#<i:1 - Sous-expression de la liste des décalages pour la cellule et tous ses voisins.
    • <i:1 - La liste des entiers compris entre 1 et -1 inclus.
    • ,{3#- Faites trois copies de la liste ( 3#) et prenez le produit cartésien ( ,{).
  • (,{3#<i:1)|.&><- Pour chaque ensemble de décalages 3D, déplacez la matrice. À un coût de 3 caractères, vous pouvez changer |.&>pour |.!.0&>ne pas avoir wrap-around.
  • [:+/ - Additionnez toutes les planches décalées ensemble.
  • ((1&<*<&8)@-*]+.5=-)~- Le long verbe externe était un crochet donc il reçoit la planche à gauche et à droite, et le côté à droite que nous avons décalé et sommé. L' ~échange ceci autour de ce verbe intérieur.
    • 5=- - 1 dans chaque cellule que la somme des cartes décalées moins la carte d'origine (c'est-à-dire le nombre de voisins) est égale à 5 et 0 dans toutes les autres.
    • ]+. - Logique OU ce qui précède avec la carte d'origine.
    • (1&<*<&8) - 1 si le nombre étant comparé entre 1 et 8 exclus, 0 sinon.
    • (1&<*<&8)@-* - Comparez (comme ci-dessus) le nombre de voisins et multipliez (c'est-à-dire ET logique lorsque le domaine n'est que 1 ou 0) le résultat OU logique par cela.

L'utilisation est la même qu'avec l'APL, il suffit d'appliquer la fonction à la carte initiale pour chaque étape. J dispose d'un opérateur de puissance fonctionnelle ^:pour vous faciliter la tâche.

   life =: (((1&<*<&8)@-*]+.5=-)~[:+/(,{3#<i:1)|.&><)  NB. for convenience
   board =: 1 = ?. 4 4 4 $ 4  NB. "random" 4x4x4 board with approx 1/4 ones
   <"2 board  NB. we box each 2D plane for easier viewing
+-------+-------+-------+-------+
|0 0 0 0|1 1 0 0|0 1 0 0|0 0 1 0|
|0 1 0 0|0 0 0 0|0 0 0 1|1 0 0 0|
|0 0 0 0|0 0 1 0|0 1 0 0|0 0 0 1|
|1 1 0 0|1 0 0 0|0 0 0 1|0 1 1 0|
+-------+-------+-------+-------+
   <"2 life board
+-------+-------+-------+-------+
|0 0 0 0|0 1 0 1|0 1 0 0|0 0 1 0|
|1 1 1 1|0 0 0 0|0 0 0 1|1 1 0 0|
|0 0 0 0|0 0 1 1|0 1 0 0|0 0 0 1|
|1 0 0 0|1 0 0 1|0 0 0 1|0 1 1 1|
+-------+-------+-------+-------+
   <"2 life^:2 board  NB. two steps
+-------+-------+-------+-------+
|0 0 0 0|0 1 0 0|0 1 0 0|0 0 0 0|
|0 1 0 0|0 0 0 0|0 0 0 1|0 1 0 0|
|0 0 0 0|0 0 0 0|0 1 0 0|0 0 0 0|
|0 0 0 0|0 0 0 1|0 0 0 0|0 1 1 1|
+-------+-------+-------+-------+
   <"2 life^:3 board  NB. etc
+-------+-------+-------+-------+
|0 1 0 0|1 1 1 0|0 1 0 0|0 1 0 0|
|0 1 0 0|1 0 1 0|1 0 1 0|1 1 1 0|
|1 0 0 0|0 0 0 0|0 1 0 0|0 1 0 0|
|0 0 1 0|0 0 0 0|0 1 0 0|0 1 1 0|
+-------+-------+-------+-------+

Je dis "aléatoire" parce que la ?.primitive donne des résultats aléatoires reproductibles en utilisant une graine fixe à chaque fois. ?est le vrai RNG.

algorithmshark
la source
Malédiction J et son |.verbe grossier !! Bon travail.
Tobia