Skip to content

Instantly share code, notes, and snippets.

@whoisjake
Forked from unclebob/gist:526188
Created September 5, 2010 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whoisjake/566115 to your computer and use it in GitHub Desktop.
Save whoisjake/566115 to your computer and use it in GitHub Desktop.
(ns life (:use clojure.test clojure.set))
(def under-populated 1)
(def over-populated 4)
(def fertile 3)
(defn north [[x y]] [x (inc y)])
(defn south [[x y]] [x (dec y)])
(defn east [[x y]] [(inc x) y])
(defn west [[x y]] [(dec x) y])
(defn north-west [cell] (-> cell north west))
(defn south-west [cell] (-> cell south west))
(defn north-east [cell] (-> cell north east))
(defn south-east [cell] (-> cell south east))
(def directions [north south east west north-west south-west north-east south-east])
(defn neighbors-of [cell]
(set (map #(% cell) directions)))
(defn candidates-for-next-generation [world]
(set
(apply concat
(map
#(conj (neighbors-of %) %)
world))))
(defn neighbor-count [cell world]
(count
(select
#(contains? world %)
(neighbors-of cell))))
(defn survives? [cell world]
(let [
neighbors (neighbor-count cell world)
]
(and
(< neighbors over-populated)
(> neighbors under-populated)
(contains? world cell))))
(defn born? [cell world]
(= fertile (neighbor-count cell world)))
(defn should-live? [cell world]
(or
(born? cell world)
(survives? cell world)))
(defn next-generation [world]
(select
#(should-live? % world)
(candidates-for-next-generation world)))
(def blinker #{[1 1] [1 2] [1 3]})
(def glider #{[3 2] [4 3] [5 3] [5 2] [5 1]})
(def next-glider #{[4 1] [5 2] [6 2] [5 3] [4 3]})
(def hive #{[3 3] [2 4] [4 4] [2 5] [4 5] [3 6]})
(def closed-beacon #{[2 2] [2 3] [3 2] [3 3] [4 4] [4 5] [5 4] [5 5]})
(def open-beacon #{[2 2] [2 3] [3 2] [4 5] [5 4] [5 5]})
(testing "what are the neighbors of a cell"
(is (= #{[3 4] [4 4] [5 4] [3 5] [5 5] [3 6] [4 6] [5 6]} (neighbors-of [4 5]))))
(testing "what are the candidates for the next generation around a blinker"
(is
(= #{[0 0] [1 0] [2 0] [0 1] [1 1] [2 1] [0 2] [1 2] [2 2] [0 3] [1 3] [2 3] [0 4] [1 4] [2 4]}
(candidates-for-next-generation blinker))))
(testing "there are no neighbors in an empty world"
(is (= 0 (neighbor-count [0 0] #{}))))
(testing "there are two neighbours of the middle of a blinker"
(is (= 2 (neighbor-count [1 2] blinker))))
(testing "lone cell dies"
(is (= #{} (next-generation #{[1 1]}))))
(testing "the hive survives"
(is (= hive (next-generation hive))))
(testing "closed beacon opens"
(is (= open-beacon (next-generation closed-beacon))))
(testing "open beacon closes"
(is (= closed-beacon (next-generation open-beacon))))
(testing "glider glides"
(is (= next-glider (next-generation glider))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment