Implementa il gioco della vita in 3D


17

La sfida è trovare l'implementazione più breve del gioco della vita in 3D ( esempio ). Queste sono le regole:

Le cellule (in questo caso, i cubi) con solo 1 o meno vicini muoiono, come per solitudine.
Se esattamente 5 cellule circondano una cella vuota, si riproducono e la riempiono.
Se una cellula ha 8 o più vicini, muore per sovraffollamento.

Rendilo almeno un 10x10x10, in cui i livelli vengono emessi singolarmente in questo modo:

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

Naturalmente, viene accettata anche una simulazione 3D grafica.
La posizione iniziale può essere codificata ma deve funzionare se viene cambiata in qualsiasi posizione iniziale. Deve essere in grado di calcolare qualsiasi numero di generazioni e l'utente deve essere in grado di richiedere manualmente la generazione successiva.

Vince il codice più corto in caratteri!

Ho realizzato questa mia implementazione per qualsiasi dimensione (cubo): http://jensrenders.site88.net/life3D.htm Puoi usarlo per testare e puoi basare il tuo codice sul mio, anche se non l'ho commentato .


1
È implicito che il tag code-golf della tua dichiarazione trovi l'implementazione più breve . Si prega di verificare se è quello che vuoi. Dovresti anche fornire alcuni dettagli su come inserire, quanti cicli, sì / no animati, ... perché è essenziale che il code-golf abbia una specifica solida.
Howard,

@Howard ho aggiunto qualche altra specifica, e sì, ho dimenticato il tag code-golf;) grazie per quello.
Jens rende il

@PeterTaylor Sì, esattamente 5, lo modificherò.
Jens Renders,

Vorrei aggiungere dettagli sul formato di output (ad esempio ogni cella deve essere separata da uno spazio come nel tuo esempio, una nuova riga tra ogni livello della griglia dell'output, le celle viventi e morte devono essere rappresentate da caratteri diversi e questi devono essere caratteri visibili .) Inoltre, tieni presente che se incorniciato come code-golf, è improbabile che tu abbia simulazioni grafiche.
Jonathan Van Matre,

Intendevi davvero vietare tutte le scappatoie discusse in quel meta thread, o solo quelle che soddisfano i criteri di (dis) approvazione (punteggio +5, almeno il doppio dei voti positivi rispetto a quelli negativi)? Perché sono sicuro di poter pensare totalmente ad alcune "scappatoie" piuttosto interessanti da discutere ... ;-)
Ilmari Karonen,

Risposte:


14

Mathematica - 120 byte

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}},##]&

Certamente non un contendente per la vittoria, ma non era mia intenzione. Inoltre, questo potrebbe probabilmente essere risolto in modo significativo semplicemente capendo il numero della regola. Volevo solo scrivere una visualizzazione (anche se in realtà sono sicuro che ce ne siano già tantissime). Quindi eccoci):

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

E dopo aver sperimentato un sacco di condizioni iniziali, ho ottenuto cose come le seguenti:

inserisci qui la descrizione dell'immagine

Ed eccone uno con una dimensione della griglia di 20x20x20. Sono stati necessari alcuni secondi per simulare e eseguire il rendering:

inserisci qui la descrizione dell'immagine

A proposito, questo presuppone condizioni al contorno periodiche.


Quelli stanno davvero entrando in uno stato di equilibrio, o è solo l'arresto dell'animazione? Se il primo, mi hai dato delle idee
chiare

1
@Kroltan È passato un po 'di tempo, ma sono abbastanza sicuro che stessero raggiungendo un equilibrio.
Martin Ender,

1
Bene grazie. Le singole sezioni dell'equilibrio sembrano molto room-map-y, per esempio, un gioco simile a rougel.
Kroltan,

12

APL, 46

Mi ci è voluto del tempo, ma sono arrivato a 46 caratteri:

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

Questa è una funzione che prende una matrice 3D booleana di qualsiasi dimensione e calcola la generazione successiva, secondo le regole date. Le condizioni al contorno non sono state specificate, quindi ho scelto di avvolgere l'altro lato, come nello spazio toroidale.

Spiegazione

{                           ⊂⍵}   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

Il risultato intermedio mè una matrice con la stessa forma della matrice originale, che conta per ogni elemento quante celle sono vive nel suo vicinato 3 × 3 × 3, incluso se stesso. Poi:

           |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.

Esempio

Definisci una matrice casuale 4 × 4 × 4 con circa 1/3 celle = 1 e calcola la sua prima e seconda generazione. La ⊂[2 3]parte anteriore è solo un trucco per stampare gli aerei in orizzontale anziché in verticale:

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

+1 Risposta molto bella! e in effetti, i confini non sono stati specificati, quindi è consentito avvolgere.
Jens Renders,

9

J - 42 caratteri

Stiamo assumendo una tavola toroidale (che avvolge) in tutte e tre le dimensioni. La visualizzazione automatica dei risultati di J sembra seguire le specifiche di output, usando 1per le celle vive e 0per quelle morte. Questo codice funziona su schede di qualsiasi larghezza, lunghezza e altezza (può essere 10x10x10, 4x5x6 e così via).

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

Segue una spiegazione:

  • ,{3#<i:1 - Sottoespressione dell'elenco di offset per la cella e tutti i suoi vicini.
    • <i:1 - L'elenco di numeri interi compresi tra 1 e -1 inclusi.
    • ,{3#- Fai tre copie dell'elenco ( 3#) e prendi il prodotto cartesiano ( ,{).
  • (,{3#<i:1)|.&><- Per ogni set di offset 3D, spostare l'array. Ad un costo di 3 caratteri, si può cambiare |.&>per |.!.0&>non avere avvolgente.
  • [:+/ - Sommare tutte le schede spostate insieme.
  • ((1&<*<&8)@-*]+.5=-)~- Il lungo verbo esterno era un uncino, quindi riceve il tabellone a sinistra e a destra, e il lato a destra ci siamo spostati e sommati. Il~ scambia con questo verbo interiore.
    • 5=- - 1 in ogni cella in cui la somma delle schede spostate meno la scheda originale (ovvero il conteggio dei vicini) è uguale a 5 e 0 in tutte le altre.
    • ]+. - O logico sopra con la scheda originale.
    • (1&<*<&8) - 1 se il numero viene confrontato tra 1 e 8 esclusivi, 0 altrimenti.
    • (1&<*<&8)@-* - Confronta (come sopra) il conteggio dei vicini e moltiplica (cioè AND logico quando il dominio è solo 1 o 0) per questo risultato logico OR.

L'utilizzo è come con l'APL, basta applicare la funzione alla scheda iniziale per ogni passaggio. J ha un operatore di potenza funzionale ^:per renderlo facile.

   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|
+-------+-------+-------+-------+

Dico "casuale" perché la ?.primitiva dà risultati casuali riproducibili usando ogni volta un seme fisso. ?è il vero RNG.


Maledizione di J e il suo |.verbo volgare !! Buon lavoro.
Tobia,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.