Skip to content

Instantly share code, notes, and snippets.

@scramjet
Created September 5, 2018 03:04
Show Gist options
  • Save scramjet/8234514fe86f572cb9dd95f0e4d86849 to your computer and use it in GitHub Desktop.
Save scramjet/8234514fe86f572cb9dd95f0e4d86849 to your computer and use it in GitHub Desktop.
Game of life in Clojure
(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