セルオートマトン(2次元)

セルオートマトン
2次元のセルオートマトン

# ルール:
(1) cell[i,j]が0であり、かつ、周りの8つのセルに「1」の状態であるセルが2つある時に、cell[i,j]の次世代での状態は「1」となる
(2) cell[i,j]が1であり、かつ、周りの8つのセルに「1」の状態であるセルが1つか2つある時に、cell[i,j]の次世代での状態は「1」のままである
(3) (1)と(2)以外は全て「0」とする

解答例

par(mfrow=c(7,7)); par(mai=c(1/10,1/10,1/10,1/10));
nGen=48;nR=75;nC=75;
field=matrix(0,nR,nC);field[37:38,37:38]=1
image(field,xaxt='n',yaxt='n')
for (i_gen in 1:nGen){
  field2=cbind(field[,nC],field,field[,1])
  field3=rbind(field2[nR,],field2,field2[1,])
  field.temp=matrix(0,nrow=nR+2,ncol=nC+2);
  for (i_row in 2:(nR+1)){
    for (i_col in 2:(nC+1)){
      nOnes=sum(field3[i_row-1,(i_col-1):(i_col+1)])+
         (field3[i_row,i_col-1]+field3[i_row,i_col+1])+
         sum(field3[i_row+1,(i_col-1):(i_col+1)])
      if (nOnes==2) {
         field.temp[i_row,i_col]=1
      } 
    if (nOnes==1 & field3[i_row,i_col]==1) {
       field.temp[i_row,i_col]=1}
    }
  }
  field=field.temp[2:(nR+1),2:(nC+1)]
  image(field,xaxt='n',yaxt='n')
}

セルオートマトン(1次元)

セルオートマトン

nCell=201;nGen=100;
res=matrix(0,nrow=nGen,ncol=nCell)
res[1,ceiling(nCell/2)]=1;
for (i_gen in 2:nGen) {
  temp.vec=c(res[i_gen-1,nCell],res[i_gen-1,],res[i_gen-1,1])
  res[i_gen,]=(temp.vec[1:nCell]+temp.vec[2:(nCell+1)]+temp.vec[3:(nCell+2)])%%2;
}
# その1R(直感的に理解しやすい例)
for (i_gen in 2:nGen) {
  for (i_cell in 2:(nCell-1)) {
    res[i_gen,i_cell]=sum(res[i_gen-1,(i_cell-1):(i_cell+1)])%%2;
  }
  res[i_gen,1]=(res[i_gen-1,nCell]+res[i_gen-1,1]+res[i_gen-1,2])%%2;
  res[i_gen,nCell]=(res[i_gen-1,(nCell-1)]+res[i_gen-1,nCell]+res[i_gen-1,1])%%2;
}

解答例その2 256のルールに対応

dec2bin<-function(num, digits=8) {
  bin=c()
  if (num==0){
    bin=0
  } else {
    while(num!=0){
      rem=num%%2
     num=num%/%2
      bin=c(rem,bin)
    }
  }
  if (length(bin) < digits){
    res=matrix(0,nrow=1,ncol=digits)
    res[(digits-length(bin)+1):digits]=bin
  } else {res=bin}
  return(res)
}

transFUN<-function(st,ruleID){
  output=dec2bin(ruleID,8);
  a=matrix(c(1,1,1,1,1,0,1,0,1,1,0,0,0,1,1,0,1,0,0,0,1,0,0,0),nrow=8,byrow=T)
  newSt=output[which(apply(a,1,function(x) {all(x==st)}))]
  return(newSt)
}
ECA<-function(nCell, nGen,ruleID){
  res=matrix(0,nrow=nGen,ncol=nCell)
  res[1,ceiling(nCell/2)]=1;
  for (i_gen in 2:nGen) {
    for (i_cell in 2:(nCell-1)) {
      res[i_gen,i_cell]=transFUN(res[i_gen-1,(i_cell-1):(i_cell+1)],ruleID)
     }
   res[i_gen,1]=transFUN(c(res[i_gen-1,nCell],
                          res[i_gen-1,1],
                          res[i_gen-1,2]),ruleID)
   res[i_gen,nCell]=transFUN(c(res[i_gen-1,(nCell-1)],
                               res[i_gen-1,nCell],
                               res[i_gen-1,1]),ruleID)
  }
  return(res)
}
# その2R (計算時間の改善はほぼなし) 
ECA2<-function(nCell, nGen,ruleID){
  res=matrix(0,nrow=nGen,ncol=nCell)
  res[1,ceiling(nCell/2)]=1;
  for (i_gen in 2:nGen) {
    temp.mat=cbind(c(res[i_gen-1,nCell],res[i_gen-1,1:(nCell-1)]),res[i_gen-1,],
      c(res[i_gen-1,2:nCell],res[i_gen-1,1]))
    res[i_gen,]=apply(temp.mat,1,transFUN,ruleID)
  }
  return(res)
}