web-dev-qa-db-fra.com

Code Golf: le jeu de la vie de Conway

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:

  1. Toute cellule vivante avec moins de deux voisins vivants meurt, comme si elle était causée par une sous-population.
  2. Toute cellule vivante avec plus de trois voisins vivants meurt, comme si elle était surpeuplée.
  3. Toute cellule vivante avec deux ou trois voisins vivants vit jusqu'à la prochaine génération.
  4. Toute cellule morte avec exactement trois voisins vivants devient une cellule vivante, comme par reproduction.

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:

  • Vous devez utiliser les E/S de fichiers pour lire/écrire les fichiers.
  • Vous devez accepter un fichier d'entrée et le nombre d'itérations comme arguments
  • Vous devez générer out.txt (écraser s'il existe) dans le format spécifié
  • Vous n'avez pas besoin de gérer les bords de la planche (enveloppant, grilles infinies .etc)
  • EDIT: Vous avez besoin d'avoir des retours à la ligne dans votre fichier de sortie.

Le gagnant sera déterminé par le nombre de personnages.

Bonne chance!

76
hb2pencil

Perl, 127 129 135 caractères

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
24
pdehaan

Mathematica - 179163154 151 caractères


    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:

alt text

Vous pouvez également obtenir un graphique de la population moyenne au fil du temps:

alt text

Un joli modèle pour générer des planeurs à partir de Wikipedia

aa

AFAIK Mathematica utilise un automate cellulaire pour générer des nombres aléatoires en utilisant règle 30.

40
Dr. belisarius

MATLAB 7.8.0 (R2009a) - 174171161150138131128 124 caractères

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


Défi supplémentaire: créateur de GIF Tweetable - 136 caractères

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 :

alt text


Améliorations

  • Mise à jour 1: Changement de la matrice b d'un type logique (c'est-à-dire "booléen") à un type numérique pour se débarrasser de quelques-uns conversions.
  • Mise à jour 2: Raccourci le code de chargement du fichier et utilisé la fonction [~ # ~] magic [~ # ~] comme astuce pour créer le noyau de convolution en moins de caractères.
  • Mise à jour 3: Simplification de la logique d'indexation, remplacement de ~~b+0 avec b/42, et remplacé 'same' avec 's' comme argument pour CONV2 (et cela a étonnamment fonctionné!).
  • Mise à jour 4: Je suppose que j'aurais dû chercher en ligne d'abord, car Loren de The MathWorks a blogué sur le golf et le Game of Life plus tôt cette année. J'ai incorporé certaines des techniques discutées ici, ce qui m'a obligé à changer b en une matrice logique.
  • Mise à jour 5: Un commentaire d'Aslak Grinsted sur le blog mentionné ci-dessus suggère un algorithme encore plus court pour à la fois la logique et la convolution (en utilisant la fonction FILTER2 ), j'ai donc "incorporé" (lire "copié") ses suggestions. ;)
  • Mise à jour 6: Supprimé deux caractères de l'initialisation de b et retravaillé la logique dans la boucle pour enregistrer 1 caractère supplémentaire.
  • Mise à jour 7: Eric Sampson a souligné dans un e-mail que je pouvais remplacer cell2mat avec char, sauvegarde 4 caractères. Merci Eric!
33
gnovice

Rubis 1.9 - 189178159155 153 caractères

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.

30
Mladen Jablanović

Python - 282 caractères

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))
20
John La Rooy

Python 2.x - 210/234 caractères

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.

20
P Daddy

Haskell - 284272 232 caractères

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
14

Java, 441 ... 346


  • Mise à jour 1 Suppression de la laideur intérieure et plus de laideur
  • pdate 2 Correction d'un bug et gagné un personnage
  • pdate Utiliser beaucoup plus de mémoire et de tableaux tout en ignorant certains problèmes de limites. Probablement quelques caractères pourraient être enregistrés.
  • Mise à jour 4 Enregistré quelques caractères. Merci à BalusC.
  • Mise à jour 5 Quelques modifications mineures pour descendre en dessous de 400 et le rendre encore plus laid.
  • Mise à jour 6 Maintenant, les choses sont si codées en dur que vous pouvez lire le montant exact en une seule fois. Plus quelques économies supplémentaires.
  • pdate 7 Enchaînez l'écriture dans le fichier pour enregistrer un caractère. Plus quelques bits impairs.

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();
 }
}
10
Molehill

F #, 496

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

428

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 :)

10
Brian

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.

10
AShelly

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}}
9
Landei

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.

7
Adrian Grigore

C - 300


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);
}
5
Molehill

Javascript/Node.js - 233 236 personnages

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)
5
MooGoo

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
5
Clayton

Java, 556532517496472433428420418 381 caractères


  • 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!

4
BalusC

PHP - 365328 322 caractères.


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.

  • Mise à jour utilisez list () au lieu de $ var = $ _SERVER ["argv"] pour les deux arguments. Gentil Don
  • mis à jour + = et - = celui-ci m'a fait/facepalm heh ne peux pas croire que je l'ai manqué
  • Mise à jour sortie du fichier pour utiliser file_put_contents () une autre bonne prise par Don
  • Mise à jour suppression de l'initialisation des vars $ q et $ w qu'ils n'étaient pas utilisés
3
Nathan

c ++ - 492454 386


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';}}
2
Inverse

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

2
PaulHurleyuk

Perl - 214 caractères

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
1
Bogdev

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.

1
Robert

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);
}
1
OlivierH

é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>
1
redestructa

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

........................*...........
......................*.*...........
............**......**............**
...........*...*....**............**
**........*.....*...**..............
**........*...*.**....*.*...........
..........*.....*.......*...........
...........*...*....................
............**......................
0
dbasnett