Le défi: Écrivez le programme le plus court qui implémente l'automate cellulaire de John H. Conway Game of Life. [ lien ]
EDIT: Après environ une semaine de compétition, j'ai sélectionné un vainqueur: pdehaan , pour avoir réussi à battre la solution Matlab par n caractère avec Perl.
Pour ceux qui n'ont pas entendu parler de Game of Life, vous prenez une grille (idéalement infinie) de cellules carrées. Les cellules peuvent être vivantes (remplies) ou mortes (vides). Nous déterminons quelles cellules sont vivantes à l'étape suivante du temps en appliquant les règles suivantes:
Votre programme lira dans un fichier texte de 40x80 caractères ASCII spécifié comme argument de ligne de commande, ainsi que le nombre d'itérations (N) à effectuer. Enfin, il affichera dans un fichier ASCII out.txt l'état du système après N itérations.
Voici un exemple exécuté avec des fichiers pertinents:
in.txt:
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.............................................
.......................................X........................................
................................XXXXXX.X........................................
................................X...............................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
Répétez 100 fois:
Q:\>life in.txt 100
Sortie résultante (out.txt)
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.X...........................................
....................................X...........................................
................................XXXXX.XX........................................
................................X.....X.........................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
Les règles:
Le gagnant sera déterminé par le nombre de personnages.
Bonne chance!
A réussi à retirer quelques personnages de plus ...
$/=pop;@b=split'',<>;map{$n=-1;@b=map{++$n;/
/?$_:($t=grep/X/,@b[map{$n+$_,$n-$_}1,80..82])==3|$t+/X/==3?X:'.'}@b}1..$/;print@b
a = {2, 2, 2};
s = Export["out.txt",
CellularAutomaton[{224, {2, {a, {2, 1, 2}, a}}, {1,1}},
(ReadList[#1, Byte, RecordLists → 2>1] - 46)/ 42, #2]〚#2〛
/. {0 → ".", 1 → "X"}, "Table"] &
Invoquer avec
s["c:\life.txt", 100]
Animation:
Vous pouvez également obtenir un graphique de la population moyenne au fil du temps:
Un joli modèle pour générer des planeurs à partir de Wikipedia
AFAIK Mathematica utilise un automate cellulaire pour générer des nombres aléatoires en utilisant règle 30.
Syntaxe de la fonction: (124 caractères)
Voici la version plus facile à lire (avec des nouvelles lignes inutiles et des espaces ajoutés pour un meilleur formatage):
function l(f,N),
b=char(importdata(f))>46;
for c=1:N,
b=~fix(filter2(ones(3),b)-b/2-3);
end;
dlmwrite('out.txt',char(b*42+46),'')
Et voici comment le programme est exécuté à partir de la fenêtre de commande MATLAB:
l('in.txt',100)
Syntaxe de commande: (130 caractères)
Après un commentaire sur l'appel de fonctions avec une syntaxe de commande, j'ai creusé un peu plus et j'ai découvert que les fonctions MATLAB peut en fait être invoquées avec un format de ligne de commande (avec certaines restrictions). Vous apprenez quelque chose de nouveau chaque jour!
function l(f,N),
b=char(importdata(f))>46;
for c=1:eval(N),
b=~fix(filter2(ones(3),b)-b/2-3);
end;
dlmwrite('out.txt',char(b*42+46),'')
Et voici comment le programme est exécuté à partir de la fenêtre de commande MATLAB:
l in.txt 100
J'ai pensé pour le plaisir que je verrais si je pouvais vider la sortie dans un fichier GIF au lieu d'un fichier texte, tout en gardant le nombre de caractères en dessous de 140 (c'est-à-dire "tweetable"). Voici le code bien formaté:
function l(f,N),
b=char(importdata(f))>46;
k=ones(3);
for c=1:N+1,
a(:,:,:,c)=kron(b,k);
b=~fix(filter2(k,b)-b/2-3);
end;
imwrite(~a,'out.gif')
Bien que [~ # ~] imwrite [~ # ~] soit censé créer un GIF qui boucle indéfiniment par défaut, mon GIF ne boucle qu'une seule fois. Il s'agit peut-être d'un bogue qui a été corrigé dans les nouvelles versions de MATLAB. Donc, pour que l'animation dure plus longtemps et que les étapes d'évolution soient plus faciles à voir, j'ai laissé le délai d'image à la valeur par défaut (qui semble être d'environ une demi-seconde). Voici la sortie GIF utilisant le modèle Gosper Glider Gun :
b
d'un type logique (c'est-à-dire "booléen") à un type numérique pour se débarrasser de quelques-uns conversions.~~b+0
avec b/42
, et remplacé 'same'
avec 's'
comme argument pour CONV2 (et cela a étonnamment fonctionné!).b
en une matrice logique.b
et retravaillé la logique dans la boucle pour enregistrer 1 caractère supplémentaire.cell2mat
avec char
, sauvegarde 4 caractères. Merci Eric!f,n=$*
c=IO.read f
n.to_i.times{i=0;c=c.chars.map{|v|i+=1
v<?.?v:('...X'+v)[[83,2,-79].map{|j|c[i-j,3]}.to_s.count ?X]||?.}*''}
File.new('out.txt',?w)<<c
Edit: Gère les sauts de ligne avec 4 caractères de moins.
Peut en supprimer 7 de plus (v<?.?v:
) si vous l'autorisez à assommer les nouvelles lignes lorsque les cellules vivantes atteignent les bords.
autant faire bouger les choses ...
import sys
_,I,N=sys.argv;R=range(3e3);B=open(I).read();B=set(k for k in R if'A'<B[k])
for k in R*int(N):
if k<1:b,B=B,set()
c=sum(len(set((k+o,k-o))&b)for o in(1,80,81,82))
if(c==3)+(c==2)*(k in b):B.add(k)
open('out.txt','w').write(''.join('.X\n'[(k in B)-(k%81<1)]for k in R))
D'accord, le code à 210 caractères est une sorte de tricherie.
#coding:l1
exec'xÚ=ŽA\nÂ@E÷sŠº1ƒÆscS‰ØL™Æª··âî¿GÈÿÜ´1iÖ½;Sçu.~H®J×Þ-‰Ñ%ª.wê,šÖ§J®d꘲>cÉZË¢V䀻Eîa¿,vKAËÀå̃<»Gce‚ÿ‡ábUt¹)G%£êŠ…óbÒüíÚ¯GÔ/n×Xši&ć:})äðtÏÄJÎòDˆÐÿG¶'.decode('Zip')
Vous ne pourrez probablement pas copier et coller ce code et le faire fonctionner. Il est censé être Latin-1 (ISO-8859-1), mais je pense qu'il a été perverti dans Windows-1252 quelque part en cours de route. De plus, votre navigateur peut avaler certains des caractères non ASCII.
Donc, si cela ne fonctionne pas, vous pouvez générer le fichier à partir de caractères 7 bits anciens:
s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 3D 8E 41 5C 6E C2
40 0C 45 F7 73 8A BA 31 13 AD 83 15 11 11 C6 73 08 63 17 05 53 89 D8 4C
99 C6 AA B7 B7 AD E2 EE BF 47 C8 FF DC B4 31 69 D6 BD 3B 53 E7 75 2E 7E
48 AE 4A D7 DE 90 8F 2D 89 AD D1 25 AA 2E 77 16 EA 2C 9A D6 A7 4A AE 64
EA 98 B2 3E 63 C9 5A CB A2 56 10 0F E4 03 80 BB 45 16 0B EE 04 61 BF 2C
76 0B 4B 41 CB C0 E5 CC 83 03 3C 1E BB 47 63 65 82 FF 87 E1 62 55 1C 74
B9 29 47 25 A3 EA 03 0F 8A 07 85 F3 62 D2 FC ED DA AF 11 47 D4 2F 6E D7
58 9A 69 26 C4 87 3A 7D 29 E4 F0 04 74 CF C4 4A 16 CE F2 1B 44 88 1F D0
FF 47 B6 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29
"""
with open('life.py', 'wb') as f:
f.write(''.join(chr(int(i, 16)) for i in s.split()))
Le résultat est un fichier source valide Python 210 caractères. Tout ce que j'ai fait ici est la compression Zip utilisée sur le code source original Python. Le la vraie triche est que j'utilise des caractères non-ASCII dans la chaîne résultante. C'est toujours du code valide, c'est juste lourd.
La version non compressée pèse 234 caractères, ce qui est toujours respectable, je pense.
import sys
f,f,n=sys.argv
e=open(f).readlines()
p=range
for v in p(int(n)):e=[''.join('.X'[8+16*(e[t][i]!='.')>>sum(n!='.'for v in e[t-1:t+2]for n in v[i-1:i+2])&1]for i in p(80))for t in p(40)]
open('out.txt','w').write('\n'.join(e))
Désolé pour le défilement horizontal, mais tous les retours à la ligne ci-dessus sont requis, et je les ai comptés comme un caractère chacun.
Je n'essaierais pas de lire le code du golf. Les noms des variables sont choisis au hasard pour obtenir la meilleure compression. Oui. Je suis sérieux. Une version mieux formatée et commentée suit:
# get command-line arguments: infile and count
import sys
ignored, infile, count = sys.argv
# read the input into a list (each input line is a string in the list)
data = open(infile).readlines()
# loop the number of times requested on the command line
for loop in range(int(count)):
# this monstrosity applies the rules for each iteration, replacing
# the cell data with the next generation
data = [''.join(
# choose the next generation's cell from '.' for
# dead, or 'X' for alive
'.X'[
# here, we build a simple bitmask that implements
# the generational rules. A bit from this integer
# will be chosen by the count of live cells in
# the 3x3 grid surrounding the current cell.
#
# if the current cell is dead, this bitmask will
# be 8 (0b0000001000). Since only bit 3 is set,
# the next-generation cell will only be alive if
# there are exactly 3 living neighbors in this
# generation.
#
# if the current cell is alive, the bitmask will
# be 24 (8 + 16, 0b0000011000). Since both bits
# 3 and 4 are set, this cell will survive if there
# are either 3 or 4 living cells in its neighborhood,
# including itself
8 + 16 * (data[y][x] != '.')
# shift the relevant bit into position
>>
# by the count of living cells in the 3x3 grid
sum(character != '.' # booleans will convert to 0 or 1
for row in data[y - 1 : y + 2]
for character in row[x - 1 : x + 2]
)
# select the relevant bit
& 1
]
# for each column and row
for x in range(80)
)
for y in range(40)
]
# write the results out
open('out.txt','w').write('\n'.join(data))
Désolé, Pythonistas, pour le formatage des crochets C-ish, mais j'essayais de préciser ce que chaque crochet fermait.
import System
main=do f:n:_<-getArgs;s<-readFile f;writeFile"out.txt"$t s$read n
p '\n'_='\n'
p 'X'2='X'
p _ 3='X'
p _ _='.'
t r 0=r
t r n=t[p(r!!m)$sum[1|d<-1:[80..82],s<-[1,-1],-m<=d*s,m+d*s<3240,'X'==r!!(m+d*s)]|m<-[0..3239]]$n-1
Il suffit de jouer avec la solution de BalusC. Une réputation limitée signifie que je ne pourrais rien ajouter de commentaire à la sienne.
class M{public static void main(String[]a)throws Exception{int t=3240,j=t,i=new Integer(a[1])*t+t;char[]b=new char[i+t],p={1,80,81,82};for(new Java.io.FileReader(a[0]).read(b,t,t);j<i;){char c=b[j],l=0;for(int n:p)l+=b[j+n]/88+b[j-n]/88;b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;}new Java.io.FileWriter("out.txt").append(new String(b,j,t)).close();}}
Version plus lisible (?):
class M{
public static void main(String[]a)throws Exception{
int t=3240,j=t,i=new Integer(a[1])*t+t;
char[]b=new char[i+t],p={1,80,81,82};
for(new Java.io.FileReader(a[0]).read(b,t,t);j<i;){
char c=b[j],l=0;
for(int n:p)l+=b[j+n]/88+b[j-n]/88;
b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;
}
new Java.io.FileWriter("out.txt").append(new String(b,j,t)).close();
}
}
Je pourrais réduire cela beaucoup, mais j'aime ça car c'est toujours dans le stade et assez lisible.
open System.IO
let mutable a:_[,]=null
let N y x=
[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]
|>Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X' then 1 else 0 with _->0)
[<EntryPoint>]
let M(r)=
let b=File.ReadAllLines(r.[0])
a<-Array2D.init 40 80(fun y x->b.[y].[x])
for i=1 to int r.[1] do
a<-Array2D.init 40 80(fun y x->
match N y x with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
File.WriteAllLines("out.txt",Array.init 40(fun y->
System.String(Array.init 80(fun x->a.[y,x]))))
0
ÉDITER
Sur demande, voici mon prochain coup de couteau:
open System
let mutable a,k=null,Array2D.init 40 80
[<EntryPoint>]
let M r=
a<-k(fun y x->IO.File.ReadAllLines(r.[0]).[y].[x])
for i=1 to int r.[1] do a<-k(fun y x->match Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X'then 1 else 0 with _->0)[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
IO.File.WriteAllLines("out.txt",Array.init 40(fun y->String(Array.init 80(fun x->a.[y,x]))))
0
C'est une réduction de 14% avec du golf de base. Je ne peux pas m'empêcher de penser que je perds en utilisant un tableau 2D/tableau de chaînes plutôt qu'un tableau 1D, mais je n'ai pas envie de faire cette transformation maintenant. Notez comment j'ai lu le fichier avec élégance 3200 fois pour initialiser mon tableau :)
Rubis 1.8: 178 175 caractères
f,n=$*;b=IO.read f
n.to_i.times{s=b.dup
s.size.times{|i|t=([82,1,-80].map{|o|b[i-o,3]||''}*'').count 'X'
s[i]=t==3||b[i]-t==?T??X:?.if s[i]>13};b=s}
File.new('out.txt','w')<<b
Les sauts de ligne sont importants (bien que tous puissent être remplacés par des points-virgules.)
Edit: a corrigé le problème de nouvelle ligne et a coupé 3 caractères.
Scala - 467364 339 caractères
object G{def main(a:Array[String]){val l=io.Source.fromFile(new Java.io.File(a(0)))getLines("\n")map(_.toSeq)toSeq
val f=new Java.io.FileWriter("out.txt")
f.write((1 to a(1).toInt).foldLeft(l){(t,_)=>(for(y<-0 to 39)yield(for(x<-0 to 79)yield{if(x%79==0|y%39==0)'.'else{val m=t(y-1)
val p=t(y+1);val s=Seq(m(x-1),m(x),m(x+1),t(y)(x-1),t(y)(x+1),p(x-1),p(x),p(x+1)).count('X'==_)
if(s==3|(s==2&t(y)(x)=='X'))'X'else'.'}})toSeq)toSeq}map(_.mkString)mkString("\n"))
f.close}}
Je pense qu'il y a encore beaucoup à faire ...
[Modifier] Oui, c'est:
object G{def main(a:Array[String]){var l=io.Source.fromFile(new Java.io.File(a(0))).mkString
val f=new Java.io.FileWriter("out.txt")
var i=a(1).toInt
while(i>0){l=l.zipWithIndex.map{case(c,n)=>if(c=='\n')'\n'else{val s=Seq(-83,-82,-81,-1,1,81,82,83).map(_+n).filter(k=>k>=0&k<l.size).count(l(_)=='X')
if(s==3|(s==2&c=='X'))'X'else'.'}}.mkString
i-=1}
f.write(l)
f.close}}
[Modifier] Et j'ai le sentiment qu'il y a encore plus à évincer ...
object G{def main(a:Array[String]){val f=new Java.io.FileWriter("out.txt")
f.write(((1 to a(1).toInt):\(io.Source.fromFile(new Java.io.File(a(0))).mkString)){(_,m)=>m.zipWithIndex.map{case(c,n)=>
val s=Seq(-83,-82,-81,-1,1,81,82,83)count(k=>k+n>=0&k+n<m.size&&m(k+n)=='X')
if(c=='\n')c else if(s==3|s==2&c=='X')'X'else'.'}.mkString})
f.close}}
La solution suivante utilise mon propre langage de programmation spécifique au domaine personnalisé que j'ai appelé NULL:
3499538
Au cas où vous vous demandez comment cela fonctionne: ma langue consiste en une seule déclaration par programme. L'instruction représente un ID de thread StackOverflow appartenant à un thread de golf de code. Mon compilateur compile cela dans un programme qui recherche la meilleure solution javascript (avec l'API SO), la télécharge et l'exécute dans un navigateur Web.
Le temps d'exécution pourrait être meilleur pour les nouveaux threads (cela peut prendre un certain temps pour que la première réponse Javascript mise à jour apparaisse), mais à la hausse, cela ne nécessite que très peu de compétences en codage.
Je me demandais juste à quel point ma solution Java Java pourrait aller en C. plus petite et plus laide). Réduit à 300, y compris les nouvelles lignes pour les bits du préprocesseur. Le système d'exploitation fermera et videra également le fichier.
#include<stdio.h>
#include<stdlib.h>
#define A(N)j[-N]/88+j[N]/88
int main(int l,char**a){
int t=3240,i=atoi(a[2])*t+t;
char*b=malloc(i+t),*j;
FILE*f;
fread(j=b+t,1,t,fopen(a[1],"r"));
for(;j-b-i;j++[t]=*j>10?l==3|l+*j==90?88:46:10)
l=A(1)+A(80)+A(81)+A(82);
fwrite(j,1,t,f=fopen("out.txt","w"));
fclose(f);
}
a=process.argv
f=require('fs')
m=46
t=f.readFileSync(a[2])
while(a[3]--)t=[].map.call(t,function(c,i){for(n=g=0;e=[-82,-81,-80,-1,1,80,81,82][g++];)t[i+e]>m&&n++
return c<m?c:c==m&&n==3||c>m&&n>1&&n<4?88:m})
f.writeFile('out.txt',t)
MUMPS: 314 caractères
L(F,N,R=40,C=80)
N (F,N,R,C)
O F:"RS" U F D C F
.F I=1:1:R R L F J=1:1:C S G(0,I,J)=($E(L,J)="X")
F A=0:1:N-1 F I=1:1:R F J=1:1:C D S G(A+1,I,J)=$S(X=2:G(A,I,J),X=3:1,1:0)
.S X=0 F i=-1:1:1 F j=-1:1:1 I i!j S X=X+$G(G(A,I+i,J+j))
S F="OUT.TXT" O F:"WNS" U F D C F
.F I=1:1:R F J=1:1:C W $S(G(N,I,J):"X",1:".") W:J=C !
Q
Mise à jour 1: remplacé le 1er StringBuffer
par Appendable
et le 2e par char[]
. Enregistré 24 caractères.
Mise à jour 2: a trouvé un moyen plus court de lire le fichier dans char[]
. Enregistré 15 caractères.
Mise à jour 3: a remplacé une if/else
Par ?:
Et a fusionné les déclarations char[]
Et int
. Enregistré 21 caractères.
Mise à jour 4: a remplacé (int)f.length()
Et c.length
Par s
. Enregistré 24 caractères.
Mise à jour 5: fait des améliorations selon les indices de Molehill. Le principal codait en dur la longueur des caractères afin que je puisse me débarrasser de File
. Enregistré 39 caractères.
Mise à jour 6: refactoring mineur. Enregistré 6 caractères.
Mise à jour 7: remplacé Integer#valueOf()
par new Integer()
et refactorisé pour la boucle. Enregistré 8 caractères.
Mise à jour 8: Amélioration du calcul du voisin. Enregistré 2 caractères.
pdate 9: Lecture de fichier optimisée car la longueur du fichier est déjà codée en dur. Enregistré 37 caractères.
import Java.io.*;class L{public static void main(String[]a)throws Exception{int i=new Integer(a[1]),j,l,s=3240;int[]p={-82,-81,-80,-1,1,80,81,82};char[]o,c=new char[s];for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;o[j]=c[j]>13?l==3|l+c[j]==90?88:'.':10;}Writer w=new FileWriter("out.txt");w.write(c);w.close();}}
Version plus lisible:
import Java.io.*;
class L{
public static void main(String[]a)throws Exception{
int i=new Integer(a[1]),j,l,s=3240;
int[]p={-82,-81,-80,-1,1,80,81,82};
char[]o,c=new char[s];
for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){
l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;
o[j]=c[j]>10?l==3|l+c[j]==90?88:'.':10;
}
Writer w=new FileWriter("out.txt");w.write(c);w.close();
}
}
La fermeture après l'écriture est absolument obligatoire, sinon le fichier est laissé vide. Sinon, cela aurait sauvé 21 autres caractères.
De plus, je pouvais également enregistrer un autre caractère lorsque j'utilisais 46
Au lieu de '.'
, Mais les saccades javac et Eclipse avec une erreur de compilation Perte de précision possible . Trucs bizarres.
Remarque: cela attend un fichier d'entrée avec \n
Sauts de ligne, pas \r\n
Comme Windows par défaut utilise!
list(,$n,$l) = $_SERVER["argv"];
$f = file( $n );
for($j=0;$j<$l;$j++){
foreach($f as $k=>$v){
$a[$k]="";
for($i=0;$i < strlen( $v );$i++ ){
$t = 0;
for($m=-1;$m<2;$m++){
for($h=-1;$h<2;$h++){
$t+=ord($f[$k + $m][$i + $h]);
}
}
$t-=ord($v[$i]);
$a[$k] .= ( $t == 494 || ($t == 452 && ord($v[$i])==88)) ? "X" : "." ;
}
}
$f = $a;
}
file_put_contents("out.txt", implode("\n", $a ));
Je suis sûr que cela peut être amélioré, mais j'étais curieux de savoir à quoi cela ressemblerait en PHP. Peut-être que cela inspirera quelqu'un qui a un peu plus d'expérience avec le golf de code.
mon premier code golf;)
#include<fstream>
#define B(i,j)(b[i][j]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);v[1]="out.txt";char b[40][83];for(i=0;i<40;++i)f.getline(b[i],83);std::ofstream g("out.txt");g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){int k=B(i-1,j)+B(i+1,j)+B(i,j-1)+B(i,j+1)+B(i-1,j-1)+B(i+1,j+1)+B(i+1,j-1)+B(i-1,j+1);(B(i,j)&&(k<2||k>3))?g<<'.':(!B(i,j)&&k==3)?g<<'X':g<<b[i][j];}g<<".\n";}g<<b[0]<<'\n';}}
Une version quelque peu révisée, remplaçant une partie de la logique par une recherche de table + quelques autres astuces mineures:
#include<fstream>
#define B(x,y)(b[i+x][j+y]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);*v="out.txt";char b[40][83], O[]="...X.....";for(i=0;i<40;++i)f>>b[i];std::ofstream g(*v);g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){O[2]=b[i][j];g<<O[B(-1,0)+B(1,0)+B(0,-1)+B(0,1)+B(-1,-1)+B(1,1)+B(1,-1)+B(-1,1)];}g<<".\n";}g<<b[0]<<'\n';}}
R 340 caractères
cgc<-function(i="in.txt",x=100){
require(simecol)
z<-file("in.txt", "rb")
y<-matrix(data=NA,nrow=40,ncol=80)
for(i in seq(40)){
for(j in seq(80)){
y[i,j]<-ifelse(readChar(z,1) == "X",1,0)
}
readChar(z,3)
}
close(z)
init(conway) <- y
times(conway)<-1:x
o<-as.data.frame(out(sim(conway))[[100]])
write.table(o, "out.txt", sep="", row.names=FALSE, col.names=FALSE)
}
cgc()
Je pense que c'est un peu tricher d'avoir un module complémentaire qui fait les automates réels pour vous, mais je vais avec parce que je devais encore me débattre avec des matricies et des trucs à lire dans le fichier avec 'X' au lieu de 1.
Ceci est mon premier "golf de code", intéressant ....
Quoi, pas encore d'entrées Perl?
$i=pop;@c=<>;@c=map{$r=$_;$u='';for(0..79)
{$K=$_-1;$R=$r-1;$u.=((&N.(&N^"\0\W\0").&N)=~y/X//
|(substr$c[$r],$_,1)eq'X')==3?'X':'.';}$u}keys@c for(1..$i);
sub N{substr$c[$R++],$K,3}open P,'>','out.txt';$,=$/;print P@c
Courir avec:
conway.pl infile #times
n autre Java, 361 caractères
class L{public static void main(final String[]a)throws Exception{new Java.io.RandomAccessFile("out.txt","rw"){{int e=88,p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;char[]b=new char[s];for(new Java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--){c=b[l];for(int n:p)c+=l+n>=0&l+n<s?b[l+n]/e:0;write(c>13?(c==49|(c|1)==91?e:46):10);}}};}}
Et un peu plus lisible
class L {
public static void main(final String[]a) throws Exception {
new Java.io.RandomAccessFile("out.txt","rw"){{
int e=88, p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;
char[] b = new char[s];
for (new Java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--) {
c=b[l];
for (int n:p)
c+=l+n>=0&l+n<s?b[l+n]/e:0;
write(c>13?(c==49|(c|1)==91?e:46):10);
}
}};
}
}
Très similaire à la version de Molehill. J'ai essayé d'utiliser un FileWriter différent et de compter les voisins de la cellule sans variable supplémentaire. Malheureusement, RandomAccessFile
est un nom assez long et vous devez passer un mode d'accès aux fichiers.
Rust - 469 caractères Je ne sais pas si je devrais poster ceci ici (cet article a 3 ans) mais de toute façon, mon essai sur ceci, en Rust ( 0.9):
use std::io::fs::File;fn main(){
let mut c=File::open(&Path::new(std::os::args()[1])).read_to_end();
for _ in range(0,from_str::<int>(std::os::args()[2]).unwrap()){
let mut b=c.clone();for y in range(0,40){for x in range(0,80){let mut s=0;
for z in range(x-1,x+2){for t in range(y-1,y+2){
if z>=0&&t>=0&&z<80&&t<40&&(x !=z||y !=t)&&c[t*81+z]==88u8{s +=1;}}}
b[y*81+x]=if s==3||(s==2&&c[y*81+x]==88u8){88u8} else {46u8};}}c = b;}
File::create(&Path::new("out.txt")).write(c);}
Pour les personnes intéressées, voici le code avant un golf agressif:
use std::io::fs::File;
fn main() {
let f = std::os::args()[1];
let mut c = File::open(&Path::new(f)).read_to_end();
let n = from_str::<int>(std::os::args()[2]).unwrap();
for _ in range(0,n)
{
let mut new = c.clone();
for y in range(0,40) {
for x in range(0,80) {
let mut sum = 0;
for xx in range(x-1,x+2){
for yy in range(y-1,y+2) {
if xx >= 0 && yy >= 0 && xx <80 && yy <40 && (x != xx || y != yy) && c[yy*81+xx] == 88u8
{ sum = sum + 1; }
}
}
new[y*81+x] = if sum == 3 || (sum == 2 && c[y*81+x] == 88u8) {88u8} else {46u8};
}
}
c = new;
}
File::create(&Path::new("out.txt")).write(c);
}
ét voilà vous voudrez peut-être utiliser ce fichier html. pas d'entrée de fichier, mais une zone de texte qui fait l'affaire! il y a aussi du html et de l'initiation et des vars. la routine principale ne comporte que 235 caractères. C'est JS minifié à la main.
<!DOCTYPE html>
<html><body><textarea id="t" style="width:600px;height:600px;font-family:Courier">
</textarea></body><script type="text/javascript">var o,c,m=new Array(3200),
k=new Array(3200),y,v,l,p;o=document.getElementById("t");for(y=0;y<3200;y++)
{m[y]=Math.random()<0.5;}setInterval(function(){p="";for(y=0;y<3200;y++){c=0;
for(v=-1;v<2;v+=2){c+=m[y-1*v]?1:0;for(l=79;l<82;l++)c+=m[y-l*v]?1:0;}
k[y]=c==3||m[y]&&c==2;}p="";for(y=0;y<3200;y++){p+=(y>0&&y%80==0)?"\n":"";
m[y]=k[y];p+=(m[y]?"O":"-");}o.innerHTML=p;},100);</script></html>
L'un des modèles classiques
***
..*
.*
Mon avatar a été créé en utilisant ma version du Game of Life en utilisant ce modèle et cette règle (notez que ce n'est pas le 23/3):
#D Thanks to my daughter Natalie
#D Try at cell size of 1
#R 8/1
#P -29 -29
.*********************************************************
*.*******************************************************.*
**.*****************************************************.**
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
****************************.*.****************************
***********************************************************
****************************.*.****************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
**.*****************************************************.**
*.*******************************************************.*
.*********************************************************
À mon humble avis - lorsque j'ai appris le jeu de la vie de Conway, l'astuce n'était pas d'écrire du code court, mais du code qui pourrait rapidement créer des formes de vie complexes. En utilisant le modèle classique ci-dessus et un monde enveloppé de 594 441 cellules, le mieux que j'ai pu faire était d'environ 1000 générations/sec.
Un autre modèle simple
**********
.
................*
.................**
................**.......**********
Et les planeurs
........................*...........
......................*.*...........
............**......**............**
...........*...*....**............**
**........*.....*...**..............
**........*...*.**....*.*...........
..........*.....*.......*...........
...........*...*....................
............**......................