Task: Wireworld







Python: 

from io import StringIO
from collections import namedtuple
from pprint import pprint as pp
import copy

WW = namedtuple('WW', 'world, w, h')
head, tail, conductor, empty = allstates = 'Ht. '


infile = StringIO()

def readfile(f):
    
    world  = [row.rstrip('\r\n') for row in f]
    height = len(world)
    width  = max(len(row) for row in world)
    
    nonrow = [ " %*s " % (-width, "") ]
    world  = nonrow + \
               [ " %*s " % (-width, row) for row in world ] + \
               nonrow   
    world = [list(row) for row in world]
    return WW(world, width, height)

def newcell(currentworld, x, y):
    istate = currentworld[y][x]
    assert istate in allstates, 'Wireworld cell set to unknown value "%s"' % istate
    if istate == head:
        ostate = tail
    elif istate == tail:
        ostate = conductor
    elif istate == empty:
        ostate = empty
    else: 
        n = sum( currentworld[y+dy][x+dx] == head
                 for dx,dy in ( (-1,-1), (-1,+0), (-1,+1),
                                (+0,-1),          (+0,+1),
                                (+1,-1), (+1,+0), (+1,+1) ) )
        ostate = head if 1 <= n <= 2 else conductor
    return ostate

def nextgen(ww):
    'compute next generation of wireworld'
    world, width, height = ww
    newworld = copy.deepcopy(world)
    for x in range(1, width+1):
        for y in range(1, height+1):
            newworld[y][x] = newcell(world, x, y)
    return WW(newworld, width, height)

def world2string(ww):
    return '\n'.join( ''.join(row[1:-1]).rstrip() for row in ww.world[1:-1] )

ww = readfile(infile)
infile.close()

for gen in range(10):
    print ( ("\n%3i " % gen) + '=' * (ww.w-4) + '\n' )
    print ( world2string(ww) )
    ww = nextgen(ww)





Ada: with Ada.Text_IO;  use Ada.Text_IO;

procedure Test_Wireworld is
   type Cell is (' ', 'H', 't', '.');
   type Board is array (Positive range <>, Positive range <>) of Cell;
      
   procedure Wireworld (State : in out Board) is
      function "abs" (Left : Cell) return Natural is
      begin
         if Left = 'H' then
            return 1;
         else
            return 0;
         end if;
      end "abs";
      Above   : array (State'Range (2)) of Cell := (others => ' ');
      Left    : Cell := ' '; 
      Current : Cell;
   begin
      for I in State'First (1) + 1..State'Last (1) - 1 loop
         for J in State'First (2) + 1..State'Last (2) - 1 loop
            Current := State (I, J);
            case Current is
               when ' ' =>
                  null;
               when 'H' =>
                  State (I, J) := 't';
               when 't' =>
                  State (I, J) := '.';
               when '.' =>
                  if abs Above (       J - 1) + abs Above (       J) + abs Above (       J + 1) +
                     abs Left                                        + abs State (I,     J + 1) + 
                     abs State (I + 1, J - 1) + abs State (I + 1, J) + abs State (I + 1, J + 1)
                  in 1..2 then
                     State (I, J) := 'H';
                  else
                     State (I, J) := '.';
                  end if;
            end case;
            Above (J - 1) := Left;
            Left := Current;
         end loop;
      end loop;
   end Wireworld;
      
   procedure Put (State : Board) is
   begin
      for I in State'First (1) + 1..State'Last (1) - 1 loop
         for J in State'First (2) + 1..State'Last (2) - 1 loop
            case State (I, J) is
               when ' ' => Put (' ');
               when 'H' => Put ('H');
               when 't' => Put ('t');
               when '.' => Put ('.');
            end case;
         end loop;
         New_Line;
      end loop;
   end Put;
   Oscillator : Board := ("         ", "  tH     ", " .  .... ", "  ..     ", "         ");
begin
   for Step in 0..9 loop
      Put_Line ("Step" & Integer'Image (Step) & " 
      Wireworld (Oscillator);
   end loop;
end Test_Wireworld;