From: "Steve" <nospam_steved94@comcast.net>
Subject: Re: Request for critics
Date: Wed, 22 Mar 2006 20:29:31 -0800
Date: 2006-03-22T20:29:31-08:00 [thread overview]
Message-ID: <MvednYvAI91nvr_ZnZ2dnUVZ_uWdnZ2d@comcast.com> (raw)
In-Reply-To: dvr7a5$9o3$1@sunnews.cern.ch
I've been writing a lot of time critical code lately so my approach to
coding may be a little out of the norm, but here is some code with the same
functionality. Columns should align nicely if you view them in a fixed
pitch font.:
with Ada.Text_IO;
use Ada.Text_IO;
procedure Automata is
Size : constant := 66;
Max_Steps : constant := 31;
type Cell_State is (Active, Inactive);
type Row_Of_Cells is array (1 .. Size) of Cell_State;
type State_To_Char is array( Cell_State'Range ) of Character;
State_Char : constant State_To_Char := ( Active => '*', Inactive => '
' );
procedure Show(Row : in Row_Of_Cells) is
begin
for I in Row_Of_Cells'Range loop
Put( State_Char( Row(I) ) );
end loop;
New_Line;
end Show;
type State_Map is array( Cell_State'Range, Cell_State'Range,
Cell_State'Range ) of Cell_State;
New_State : constant State_Map :=
( Active => ( Active => ( Active => Inactive, -- Active
Active Active => Inactive
Inactive => Active ), -- Active
Active Inactive => Active
Inactive => ( Active => Inactive, -- Active
Inactive Active => Inactive
Inactive => Active ) ), -- Active
Inactive Inactive => Active
Inactive => ( Active => ( Active => Active, -- Inactive
Active Active => Active
Inactive => Inactive ), -- Inactive
Active Inactive => Inactive
Inactive => ( Active => Active, -- Inactive
Inactive Active => Active
Inactive => Inactive ) ) -- Inactive
Inactive Inactive => Inactive
);
begin
declare
Automata : Row_Of_Cells := (Size / 2 => Active, others => Inactive);
begin
Show(Automata);
for Step in 1 .. Max_Steps loop
declare
New_Automata : Row_Of_Cells := (others => Inactive);
begin
for Cell_Index in
Row_Of_Cells'First + 1 .. Row_Of_Cells'Last - 1 loop
New_Automata(Cell_Index) := New_State(
Automata(Cell_Index - 1),
Automata(Cell_Index),
Automata(Cell_Index + 1));
end loop;
Automata := New_Automata;
end;
Show(Automata);
end loop;
end;
end Automata;
"Maciej Sobczak" <no.spam@no.spam.com> wrote in message
news:dvr7a5$9o3$1@sunnews.cern.ch...
> For the purpose of my learning, please criticise the following code:
[snip]
> <problem-description>
> The above is a short simulation of one particular 1D cellular automata
> (the state of the whole automata is printed as a single line and the time
> progresses downwards on the printout), where the next state of each cell
> is a function of the current states in the immediate neighbourhood of the
> given cell. In other words, given ABCDEFGH as a state of the automata, the
> next state of cell D is a function of cells C, D and E. Taking two
> possible states, there are 256 possible rules. The above program simulates
> only one of them.
> </problem-description>
>
> The goal is the readability and proper expression of the problem.
>
> How do you name loop control variables for array traversals? Is
> "Cell_Index" overly verbose and would be "I" just enough?
>
In this example of code, IMHO "I" would be enough.
There is only one index involved and the loop is small. Personally I tend
to use a more expressive index name for all cases, and would probably use
Cell_Index, Data_Index, Index, or something similar.
> Would you drop the Cell_Triplet type and pass the neighbourhood as three
> separate parameters instead?
>
In this case I would rop Cell_Triplet since it doesn't add anything to the
readability and introduces a new data type and required conversions. In my
experience, for the simple cases less is better.
> And so on. Pleasy be picky with every aspect you find important.
>
> Any performance considerations for this code (except, of course, that
> Put() is called for each cell and might be replaced by whole-line
> printouts instaed)?
The performance change you'll note in my modified implementation is the use
of a lookup table for New_State instead of a function. I think it is easier
to interpret the mapping that takes place in the lookup table than analyzing
the code.
You'll also note that I moved the definition of Automata into a declare
block in the main procedure. I strive to restrict the scope of variables as
much as possible.
Normally I also avoid using variable names that are the same as package
names. It may be legal, but it may also be confusing.
In your original code the state mapping really only depended on the two
neighbors, so the State_Map really only needs to be 2x2 rather than the 3x3
in my example. I chose to implement 3x3 since it would make it easier to
define other mappings.
>
> BTW: The C version is just a bit shorter:
>
> #include <stdio.h>
> int main(){char s[]=
> " * "
> ;char p,n;int st,i;puts(s);for(st=0;st!=31;++st){p='
> ';for(i=1;i!=65;++i){n=(s[i-1]^s[i+1])|0x20;s[i-1]=p;p=n;}s[i-1]=p;puts(s);}return
> 0;}
>
> ;-) (the last three characters are not part of the program)
>
You can generate line noise in Ada too. But it is a bit harder to do, and
after all that is not the objective.
I hope this helps,
Steve
(The Duck)
> --
> Maciej Sobczak : http://www.msobczak.com/
> Programming : http://www.msobczak.com/prog/
next prev parent reply other threads:[~2006-03-23 4:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-22 10:01 Request for critics Maciej Sobczak
2006-03-22 21:44 ` Gautier
2006-03-22 23:17 ` Jeffrey R. Carter
2006-03-23 1:21 ` tmoran
2006-03-23 4:29 ` Steve [this message]
2006-03-24 23:30 ` Justin Gombos
2006-03-25 14:00 ` Stephen Leake
2006-03-26 0:35 ` Jeffrey R. Carter
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox