Ensuring sleep value is at least zero.
[cellular-automata.git] / 003 / src / life.erl
index 4c71251..605fa95 100644 (file)
@@ -7,13 +7,13 @@
 -define(CHAR_ALIVE, 111).  % "o"
 -define(CHAR_BAR,    45).  % "-"
 
--define(INTERVAL, 100).
+-define(GEN_INTERVAL, 100).
 
 
 -record(state, {x            :: non_neg_integer()
                ,y            :: non_neg_integer()
                ,n            :: pos_integer()
-               ,bar          :: string()
+               ,bar          :: nonempty_string()
                ,board        :: array()
                ,gen_count    :: pos_integer()
                ,gen_duration :: non_neg_integer()
@@ -61,17 +61,29 @@ life_loop(
         end
     ),
 
-    {NewTime, NewBoard} = timer:tc(fun() -> next_generation(X, Y, Board) end),
+    {NewTime, NewBoard} = timer:tc(
+        fun() ->
+            next_generation(X, Y, Board)
+        end
+    ),
+
     NewState = State#state{board        = NewBoard
                           ,gen_count    = GenCount + 1
                           ,gen_duration = NewTime
                           ,print_time   = PrintTime
     },
 
-    timer:sleep(?INTERVAL),
+    NewTimeMil = NewTime / 1000,
+    NextGenDelay = at_least_zero(round(?GEN_INTERVAL - NewTimeMil)),
+    timer:sleep(NextGenDelay),
+
     life_loop(NewState).
 
 
+at_least_zero(Integer) when Integer >= 0 -> Integer;
+at_least_zero(_) -> 0.
+
+
 do_print_screen(Board, Bar, X, Y, N, GenCount, Time, PrintTime) ->
     ok = do_print_status(Bar, X, Y, N, GenCount, Time, PrintTime),
     ok = do_print_board(Board).
@@ -89,7 +101,10 @@ do_print_status(Bar, X, Y, N, GenCount, TimeMic, PrintTimeMic) ->
 
 
 do_print_board(Board) ->
-    CharLists = array:to_list(
+    % It seems that just doing a fold should be faster than map + to_list
+    % combo, but, after measuring several times, map + to_list has been
+    % consistently (nearly twice) faster than either foldl or foldr.
+    RowStrings = array:to_list(
         array:map(
             fun(_, Row) ->
                 array:to_list(
@@ -106,10 +121,10 @@ do_print_board(Board) ->
     ),
 
     ok = lists:foreach(
-        fun(CharList) ->
-            ok = io:format("~s~n", [CharList])
+        fun(RowString) ->
+            ok = io:format("~s~n", [RowString])
         end,
-        CharLists
+        RowStrings
     ).
 
 
This page took 0.033702 seconds and 4 git commands to generate.