function row_next = ca_step ( row )

%*****************************************************************************80
%
%% CA_STEP computes the next row of a rule #30 cellular automaton.
%
%  Discussion:
%
%    This program carries out iterations of the 1D cellular automaton
%    known as rule 30.
%
%    Given an initial linear array of 0's and 1's, rule 30 produces a new
%    array using the rules:
%
%      111  110  101  100  011  010  001  000
%       V    V    V    V    V    V    V    V
%       0    0    0    1    1    1    1    0     
%
%    Note that there are 256 = 2^8 possible ways to fill in this output
%    chart, and that rule 30 gets its index by the fact that
%    (0,0,0,1,1,1,1,0) can be interpreted as the binary representation of 30.
%
%    For instance, if the current values of X(4), X(5) and X(6) are
%    0, 1 and 1, respectively, then the new value of X(5) will be 1.
%
%    The first and last entries of the array must be treated specially, since
%    they don't have a left or right neighbor.  One simple treatment is 
%    to assume that there are phantom neighbors whose values are both 0.
%    Another is to enforce periodic boundary conditions.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    23 October 2017
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Stephen Wolfram,
%    A New Kind of Science,
%    Wolfram Media, 2002,
%    ISBN13: 978-1579550080,
%    LC: QA267.5.C45.W67.
%
%  Parameters:
%
%    Input, integer ROW(*), the current row.
%
%    Input, integer ROW_NEXT(*), the next row.
%
  n = length ( row );

  row_next = zeros ( 1, n );

  for i = 1 : n

    if ( i == 1 )
      im1 = n;
    else
      im1 = i - 1;
    end

    if ( i == n )
      ip1 = 1;
    else
      ip1 = i + 1;
    end
%
%  The transformation rules are:
%
%  111  110  101  100  011  010  001  000
%   |    |    |    |    |    |    |    |
%   0    0    0    1    1    1    1    0
%
%  which means this rule has binary code 00011110 = 16 + 8 + 4 + 2 = 30
%
    if ( ( row(im1) == 0 && row(i) == 0 && row(ip1) == 1 ) || ...
         ( row(im1) == 0 && row(i) == 1 && row(ip1) == 0 ) || ...
         ( row(im1) == 0 && row(i) == 1 && row(ip1) == 1 ) || ...
         ( row(im1) == 1 && row(i) == 0 && row(ip1) == 0 ) )
      row_next(i) = 1;
    else
      row_next(i) = 0;
    end

  end

  return
end

