Task: Wireworld






PHP: $desc = 'tH.........
.   .
  ........
.   .
Ht.. ......

      ..
tH.... .......
      ..

      ..
tH..... ......
      ..';

$steps = 30;

$world = array(array());
$row = 0;
$col = 0;
foreach(str_split($desc) as $i){
    switch($i){
        case "\n":
            $row++;

            $col = 0;
            $world[] = array();
            break;
        case '.':
            $world[$row][$col] = 1;//conductor
            $col++;
            break;
        case 'H':
            $world[$row][$col] = 2;//head
            $col++;
            break;
        case 't':
            $world[$row][$col] = 3;//tail
            $col++;
            break;
        default:
            $world[$row][$col] = 0;//insulator/air
            $col++;
            break;
    };
};
function draw_world($world){
    foreach($world as $rowc){
        foreach($rowc as $cell){
            switch($cell){
                case 0:
                    echo ' ';
                    break;
                case 1:
                    echo '.';
                    break;
                case 2:
                    echo 'H';
                    break;
                case 3:
                    echo 't';
            };
        };
        echo "\n";
    };

};
echo "Original world:\n";
draw_world($world);
for($i = 0; $i < $steps; $i++){
    $old_world = $world; //backup to look up where was an electron head
    foreach($world as $row => &$rowc){
        foreach($rowc as $col => &$cell){
            switch($cell){
                case 2:
                    $cell = 3;
                    break;
                case 3:
                    $cell = 1;
                    break;
                case 1:
                    $neigh_heads = (int) @$old_world[$row - 1][$col - 1] == 2;
                    $neigh_heads += (int) @$old_world[$row - 1][$col] == 2;
                    $neigh_heads += (int) @$old_world[$row - 1][$col + 1] == 2;
                    $neigh_heads += (int) @$old_world[$row][$col - 1] == 2;
                    $neigh_heads += (int) @$old_world[$row][$col + 1] == 2;
                    $neigh_heads += (int) @$old_world[$row + 1][$col - 1] == 2;
                    $neigh_heads += (int) @$old_world[$row + 1][$col] == 2;
                    if($neigh_heads == 1 || $neigh_heads == 2){
                        $cell = 2;
                    };
            };
        };
        unset($cell); //just to be safe
    };
    unset($rowc); //just to be safe
    echo "\nStep " . ($i + 1) . ":\n";
    draw_world($world);
};





Fortran: program Wireworld
  implicit none
 
  integer, parameter :: max_generations = 12
  integer :: nrows = 0, ncols = 0, maxcols = 0
  integer :: gen, ierr = 0
  integer :: i, j
  character(1), allocatable :: cells(:,:)
  character(10) :: form, sub
  character(80) :: buff


  open(unit=8, file="wwinput.txt")
    

  do 
    read(8, "(a)", iostat=ierr) buff
    if(ierr /= 0) exit
    nrows = nrows + 1
    ncols = len_trim(buff)
    if(ncols > maxcols) maxcols = ncols
  end do


  allocate(cells(0:nrows+1, 0:maxcols+1))
  cells = " "


  rewind(8)
  do i = 1, nrows
    read(8, "(a)", iostat=ierr) buff
    if(ierr /= 0) exit
    do j = 1, maxcols
      cells(i, j) = buff(j:j)
    end do
  end do
  close(8)


  write(sub, "(i8)") maxcols
  form = "(" // trim(adjustl(sub)) // "a1)"
       
  do gen = 0, max_generations
    write(*, "(/a, i0)") "Generation ", gen
    do i = 1, nrows
      write(*, form) cells(i, 1:maxcols)
    end do
    call nextgen(cells)
  end do
  deallocate(cells)
  
 contains
  
  subroutine Nextgen(cells)
    character, intent(in out) :: cells(0:,0:)
    character :: buffer(0:size(cells, 1)-1, 0:size(cells, 2)-1)
    integer :: i, j, h
   
     buffer = cells   
     do i = 1, size(cells, 1)-2
        do j = 1, size(cells, 2)-2
          select case (buffer(i, j))
            case(" ")
              
                
            case("H")
              
              cells(i, j) = "t"
   
            case("t")
              
              cells(i, j) = "."
   
            case (".")
              
              
              
              
              h = sum(count(buffer(i-1:i+1, j-1:j+1) == "H", 1)) 
              if(h == 1 .or. h == 2) cells(i, j) = "H"
          end select       
        end do
     end do
  end subroutine Nextgen
end program Wireworld