Conway’s Game of Life in a tweet.
Recently, my friend pointed out me an article Life in a tweet where Game of Life was implemented in one tweet (less than 140 characters) in Ruby and F#. I took this challenge.
Here is the final version in 137
characters of Clojure:
(fn[g r](reduce(fn[i j](update-in i j(fn[v](get[v 1]
(-(apply +(map #(get-in g% 0)(for[a[-1 0 1]b[-1 0 1]]
(map + j[a b]))))v 2)0))))g r))
Translate tweet to more readable code:
(defn step-sugar [grid range]
(let [count-neighbours ;; determine number of neighbours
(fn[[i j]]
(reduce + (map #(get-in grid % 0)
(for[a [-1 0 1] b [-1 0 1]]
[(+ i a) (+ j b)]))))
new-value ;; calculate new value for cell
(fn [v [i j]]
(let [c (- (count-neighbours [i j]) v)]
(cond (= 3 c) 1
(= 2 c) v
:else 0)))
evolve-cell ;; update cell in a grid
(fn[g i] (update-in g i #(new-value % i)))]
(reduce evolve-cell grid range)))
Actually, this version is cheating,
due to passing one extra-parameter range
that contains all indices
need to be updated in form [[0 1] [1 1]]...
On the other side it gives us two features:
To use this function you need:
(def grid [[0 0 0]
[1 1 1]
[0 0 0]])
(defn evolution [g]
(let [p (count g) q (count (get g 0))
range (for [i (range p) j (range q)][i j])]
(iterate #(step-sugar % range) g)))
(defn print-grid [g]
(doseq [s (map #(apply str (replace {0 "." 1 "⚫"} %)) g)]
(println s)))
To make sure results are correct use the following
run
function and compare results to some common
examples.
(defn run [grid]
(doseq [g (evolution grid)]
(print-grid g)
(Thread/sleep 1000)))
Pattern examples:
(def block [[0 0 0 0]
[0 1 1 0]
[0 1 1 0]
[0 0 0 0]])
(def glider [[0 0 1 0 0 0 0 0]
[1 0 1 0 0 0 0 0]
[0 1 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0]])
Full history of implementation and more life patterns available here
Enjoy!
mishadoff 07 March 2013