dependencies
| (this space intentionally left almost blank) | |||
(ns evolve.core) | ||||
Let's do a bit of evolution.We have very simple bacteria, living in a world where there is plenty of food, but radiation kills. On every cycle bacteria reproduce and take more radiation; when they have enough radiation, they die. Whenever a bacterium reproduces, it transmits along its
own The world is limited to How to playFire up your repl and type: First you create a gene pool, with only 1 bacterium with a radiation resistance of 100, and 99 with a resistance of 30:
then you run a number of runs of the game. Each run is the time needed for reproduction; as a reference, in E. Coli under ideal conditions, it takes about 20 minutes.
Again, for E. Coli this is about 2 days. You'll be impressed at how quickly the system But why?I wanted to show my kids how quickly blind evolution is able to spread advances in the gene pool, and how it works in practice. It ends up as one screenshot of Clojure, including documentation, so it's not bad. | ||||
(def WORLD_SIZE 10000) | ||||
Build one bacterium. So far it only has two attributes:
| (defn bact [curr max] {:current curr :max max}) | |||
Makes a number of bacteria, all with the same genes. We'll use this to bootstrap the game with sets of different bacteria. | (defn mk-bacts [max num] (map (fn [_] (bact 0 max)) (range num))) | |||
Runs one turn for one bacterium. Returns a vector of 0 or more bacteria, as on each turn:
| (defn make-turn-single [{:keys [current max]}] (if (> current max) ; it's dead [] [; original (bact (+ 10 current) max) ; newborn (bact 0 max)])) | |||
Runs a turn of the game, by going through
all living bacteria, applying | (defn make-turn [all-bacteria] (->> (map make-turn-single all-bacteria) flatten shuffle (take WORLD_SIZE))) | |||
Prints very basic statistics on a set of bacteria. So far, it prints a vector of the E.g. This could definitely be improved. | (defn stats [all-bacteria] (map (fn [[k v]] [k (count v)]) (group-by :max all-bacteria))) | |||
Runs a game. You start it with a vector of bacteria, that you can
create in bulk with the On each turn, statistics are printed so you know the
relative prevalence of | (defn run-game [all-bacteria turns] (loop [b all-bacteria t 0] (prn "t" t "=" (stats b)) (if (> t turns) (prn "Stats at: " turns (stats b)) (recur (make-turn b) (inc t))))) | |||