Skip to content

Instantly share code, notes, and snippets.

@jingibus
Last active April 12, 2020 17:11
Show Gist options
  • Save jingibus/87526f51073f4cec0efecc5db6b7d015 to your computer and use it in GitHub Desktop.
Save jingibus/87526f51073f4cec0efecc5db6b7d015 to your computer and use it in GitHub Desktop.
(ns life.core
(:require [clojure.string :as string]))
(def map-indexedv (comp vec map-indexed))
(defn neighbors
([coords]
(neighbors coords [1 1]))
([[y x] [ystep xstep]]
(let [x-range (range (- x xstep) (+ x xstep 1) xstep)
y-range (range (- y ystep) (+ y ystep 1) ystep)]
(->> x-range
(mapcat (fn [x] (map (fn [y] [y x]) y-range)))
(filter #(not= [y x] %))))))
(defn read-initial-state
[]
(let [make-line #(->> (string/split % #"")
(map (fn [v] (if (= "O" v) "O" ".")))
vec)]
(mapv make-line (line-seq (java.io.BufferedReader. *in*)))))
(defn next-board
[board]
(let [at-coords (fn [[y x]]
(let [rows (count board)
cols (count
(some (partial get board)
(range (- y rows)
(+ y rows 1)
rows)))]
(some (partial get-in board)
(cons [y x]
(neighbors [y x] [rows cols])))))
alive? #(= "O" (at-coords %))
alive-in-region
(fn [coords]
(->> (neighbors coords)
(filter alive?)
count))
alive-next? #(if (alive? %)
(<= 2 (alive-in-region %) 3)
(= 3 (alive-in-region %)))
next-value #(if (alive-next? %) "O" ".")]
(map-indexedv
(fn [y row]
(map-indexedv
(fn [x _]
(next-value [y x]))
row))
board)))
(defn -main
[]
(println "Input board")
(let [board (read-initial-state)
print-board
(fn [board]
(doall (map #(println (string/join "" %)) board)))
play-game
(fn [last-board]
(print-board last-board)
(println)
(Thread/sleep 10)
(next-board last-board))]
(doall (iterate play-game board))))
(comment
(def example-input
".....
.OOO.
.....
")
(def test-board (mapv #(string/split % #"") (string/split example-input #"\n")))
(next-board test-board)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment