Created
September 5, 2018 03:04
-
-
Save scramjet/8234514fe86f572cb9dd95f0e4d86849 to your computer and use it in GitHub Desktop.
Game of life in Clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (ns life | |
| (:require [clojure.set :as set])) | |
| (defn neighbors [[cell-x cell-y :as cell]] | |
| (for [x (range (dec cell-x) (+ cell-x 2)) | |
| y (range (dec cell-y) (+ cell-y 2)) | |
| :let [neighbor [x y]] | |
| :when (not= neighbor cell)] | |
| neighbor)) | |
| (def X "X") | |
| (def _ " ") | |
| (defn make-board [xs] | |
| (set (for [y (range 0 (count xs)) | |
| :let [row (nth xs y)] | |
| x (range 0 (count row)) | |
| :when (= (get row x) X)] | |
| [x y]))) | |
| (def glider (make-board [[X _ X] | |
| [_ X X] | |
| [_ X _]])) | |
| (def blinker (make-board [[_ _ _] | |
| [X X X] | |
| [_ _ _]])) | |
| (def block (make-board [[X X] | |
| [X X]])) | |
| (defn make-xs [board] | |
| (let [sorted-x (vec (sort (map first board))) | |
| sorted-y (vec (sort (map second board))) | |
| min-x (nth sorted-x 0) | |
| max-x (nth sorted-x (dec (count sorted-x))) | |
| min-y (nth sorted-y 0) | |
| max-y (nth sorted-y (dec (count sorted-y)))] | |
| (for [y (range min-y (inc max-y))] | |
| (for [x (range min-x (inc max-x))] | |
| (if (contains? board [x y]) | |
| X | |
| _))))) | |
| (make-xs glider) | |
| ;; => (("X" " " "X") (" " "X" "X") (" " "X" " ")) | |
| (defn board-to-str [board] | |
| (apply str (interpose "\n" (map (partial apply str) (make-xs board))))) | |
| (board-to-str glider) | |
| ;; => X X | |
| ;; XX | |
| ;; X | |
| (defn next-board [board] | |
| (set (reduce (fn [board' cell] | |
| (let [live-neighbors (count (set/intersection board (set (neighbors cell))))] | |
| (if (contains? board cell) | |
| ;; live -> dead | |
| (if (or (< live-neighbors 2) (> live-neighbors 3)) | |
| (disj board' cell) | |
| board') | |
| ;; dead -> live | |
| (if (= live-neighbors 3) | |
| (conj board' cell) | |
| board')))) | |
| board | |
| (into board (mapcat neighbors board))))) | |
| (defn run [board steps] | |
| (->> board | |
| (iterate next-board) | |
| (take steps) | |
| (map board-to-str) | |
| (interpose "\n----\n") | |
| (apply str))) | |
| (run glider 10) | |
| ;; => X X | |
| ;; XX | |
| ;; X | |
| ;; ---- | |
| ;; X | |
| ;; X X | |
| ;; XX | |
| ;; ---- | |
| ;; X | |
| ;; XX | |
| ;; XX | |
| ;; ---- | |
| ;; X | |
| ;; X | |
| ;; XXX | |
| ;; ---- | |
| ;; X X | |
| ;; XX | |
| ;; X | |
| ;; ---- | |
| ;; X | |
| ;; X X | |
| ;; XX | |
| ;; ---- | |
| ;; X | |
| ;; XX | |
| ;; XX | |
| ;; ---- | |
| ;; X | |
| ;; X | |
| ;; XXX | |
| ;; ---- | |
| ;; X X | |
| ;; XX | |
| ;; X | |
| ;; ---- | |
| ;; X | |
| ;; X X | |
| ;; XX | |
| (run blinker 5) | |
| ;; => XXX | |
| ;; ---- | |
| ;; X | |
| ;; X | |
| ;; X | |
| ;; ---- | |
| ;; XXX | |
| ;; ---- | |
| ;; X | |
| ;; X | |
| ;; X | |
| ;; ---- | |
| ;; XXX | |
| (run block 5) | |
| ;; => XX | |
| ;; XX | |
| ;; ---- | |
| ;; XX | |
| ;; XX | |
| ;; ---- | |
| ;; XX | |
| ;; XX | |
| ;; ---- | |
| ;; XX | |
| ;; XX | |
| ;; ---- | |
| ;; XX | |
| ;; XX |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment