indexed-step
-
(-> (iterate indexed-step glider) (nth 8) pprint) is equals to (pprint (nth (iterate indexed-step glider) 8));
-
(iterate f x) means "Return a lazy sequence of x, (f x), (f (f x)) etc, f must be free of side-effects";
So (indexed-step glider) returns the next state of the board "glider" based on its current state.
(nth (iterate indexed-step glider) 8) is the 8th step of the transformation. If you want to see the 4th step just modify 8 to 4 in above code snippet.
(->> (iterate indexed-step glider) (take 5) ppr/pprint), equals to (ppr/pprint (take 5 (iterate indexed-step glider))), displays every step of the transformation from origin state to the first translational position.
The result of above code can be verified visually at [http://www.bitstorm.org/gameoflife/] (use mouse button to add/remove seed in the panel).
index-free-step
- "map", "partition" and "concat" create a lazy seq;
Why add a (repeat nil) to board in "index-free-step"?
step
- "frequencies" receives a collection, returns a map, the key is the item of the collection, the value is the number of times this item appear. So:
(frequencies [1 2 3 2 3 4]) => {1 1, 2 2, 3 2, 4 1}
-
(mapcat f coll) <=> (apply concat (map f coll));
-
"for" is the Cartesian product. So:
(for [x [:a :b] y [1 2]] [x y]) => ([:a 1] [:a 2] [:b 1] [:b 2])
(for [[x y] {1 1, 2 2, 3 2, 4 1}] [x y]) => ([1 1] [2 2] [3 2] [4 1])
and "(for [[x y] (frequencies [1 2 3 2 3 4]) :when (= y 2)] x)" select items which appear 2 times in collection.
Translate example 3-7 to plain text is:
-
The live cells are a subset of all neighbours of original live cells;
-
Every cell in the neighbour area are expressed as variable "loc", while the number of its neighbour is expressed as "n";
-
To a cell "loc", if one of the following conditions are met, it is alive:
-
It has 3 neighbours, expressd as (= n 3);
-
It has 2 neighbours and it is alive, expressed as (and (= n 2) (cells loc))
Example 3-7:
(defn step [cells] (set (for [[loc n] (frequencies (mapcat neighbours cells)) :when (or (= n 3) (and (= n 2) (cells loc)))] loc)))
stepper
-
To hex-step, the board and cells are all hexagonal, which means every cell has 6 neighbours;
-
To every cell (loc) in the neighbour area, if it is alive(tested with (cells loc) in the "for" function), it's liveness is determined with "survive?" function: (survive? n); otherwise it's determined with "(birth? n)";
-
Test 4 step oscillator:
(def init #{[0 0] [1 1] [1 3] [0 4]}) (= (-> (iterate hex-step init) (nth 4)) init)