Task: Elementary cellular automaton




Go: package main

import (
    "fmt"
    "math/big"
    "math/rand"
    "strings"
)

func main() {
    const cells = 20
    const generations = 9
    fmt.Println("Single 1, rule 90:")
    a := big.NewInt(1)
    a.Lsh(a, cells/2)
    elem(90, cells, generations, a)
    fmt.Println("Random intial state, rule 30:")
    a = big.NewInt(1)
    a.Rand(rand.New(rand.NewSource(3)), a.Lsh(a, cells))
    elem(30, cells, generations, a)
}

func elem(rule uint, cells, generations int, a *big.Int) {
    output := func() {
        fmt.Println(strings.Replace(strings.Replace(
            fmt.Sprintf("%0*b", cells, a), "0", " ", -1), "1", "#", -1))
    }
    output()
    a1 := new(big.Int)
    set := func(cell int, k uint) {
        a1.SetBit(a1, cell, rule>>k&1)
    }
    last := cells - 1
    for r := 0; r < generations; r++ {
        k := a.Bit(last) | a.Bit(0)<<1 | a.Bit(1)<<2
        set(0, k)
        for c := 1; c < last; c++ {
            k = k>>1 | a.Bit(c+1)<<2
            set(c, k)
        }
        set(last, k>>1|a.Bit(0)<<2)
        a, a1 = a1, a
        output()
    }
}








Ada: with Ada.Text_IO;
procedure Elementary_Cellular_Automaton is
   
   type t_Rule  is new Integer range 0..2**8-1;
   type t_State is array (Integer range <>) of Boolean;

   Cell_Image : constant array (Boolean) of Character := ('.', '#');

   function Image (State : in t_State) return String is
     (Cell_Image(State(State'First)) &
      (if State'Length <= 1 then ""
       else Image(State(State'First+1..State'Last))));

   
   type t_RuleA is array (Boolean, Boolean, Boolean) of Boolean;

   function Translate (Rule : in t_Rule) return t_RuleA is
      
      
      Remain : t_Rule := Rule;
   begin
      return Answer : t_RuleA do
         for K in Boolean loop
            for J in Boolean loop
               for I in Boolean loop
                  Answer(I,J,K) := (Remain mod 2 = 1);
                  Remain := Remain / 2;
               end loop;
            end loop;
         end loop;
      end return;
   end Translate;

   procedure Show_Automaton (Rule        : in t_Rule;
                             Initial     : in t_State;
                             Generations : in Positive) is
      RuleA : constant t_RuleA  := Translate(Rule);
      Width : constant Positive := Initial'Length;
      
      subtype t_State0 is t_State (0..Width-1);
      State     : t_State0 := Initial;
      New_State : t_State0;
   begin
      Ada.Text_IO.Put_Line ("Rule" & t_Rule'Image(Rule) & " :");
      for Generation in 1..Generations loop
         Ada.Text_IO.Put_Line (Image(State));
         for Cell in State'Range loop
            New_State(Cell) := RuleA(State((Cell-1) mod Width),
                                     State(Cell),
                                     State((Cell+1) mod Width));
         end loop;
         State := New_State;
      end loop;
   end Show_Automaton;

begin
   Show_Automaton (Rule        => 90,
                   Initial     => (-10..-1 => False, 0 => True, 1..10 => False),
                   Generations => 15);
   Show_Automaton (Rule        => 30,
                   Initial     => (-15..-1 => False, 0 => True, 1..15 => False),
                   Generations => 20);
   Show_Automaton (Rule        => 122,
                   Initial     => (-12..-1 => False, 0 => True, 1..12 => False),
                   Generations => 25);
end Elementary_Cellular_Automaton;