Conway's Game of Life implemented in Emacs org-mode tables
Evaluate the code in the first source block (C-c C-c), then keep
evaluating the second block for each iteration of the rules.
#+BEGIN_SRC emacs-lisp :results silent
(require 'cl) ; for loop
(defvar *empty* "")
(defvar *live* "o")
(defun make-empty-board (nrow ncol)
(loop for r from 0 below nrow
collect (loop for c from 0 below ncol collect *empty*)))
(defun get-cell (r c nrow ncol board)
(cond ((and (< -1 r nrow)
(< -1 c ncol))
(elt (elt board r) c))
(:else *empty*)))
(defun set-cell (r c val board)
(setf (elt (elt board r) c) val))
(defun count-neighbors (r c nrow ncol board)
(loop for x from (1- r) to (1+ r)
sum (loop for y from (1- c) to (1+ c)
sum (cond ((and (= x r) (= y c)) 0)
((equal *live* (get-cell x y nrow ncol board)) 1)
(:else 0)))))
(defun cell-at-next-gen (current neighbors)
(cond ((= 3 neighbors) *live*)
((and (= 2 neighbors) (equal *live* current)) *live*)
(:else *empty*)))
(defun iter-life (board)
(let* ((nrow (length board))
(ncol (length (car board)))
(next-board (make-empty-board nrow ncol)))
(loop for r from 0 below nrow
do (loop for c from 0 below ncol
do (set-cell r c
(cell-at-next-gen (get-cell r c nrow ncol board)
(count-neighbors r c nrow ncol board))
next-board)))
next-board))
#+END_SRC
#+BEGIN_SRC emacs-lisp :var board=board :results table
(iter-life board)
#+END_SRC
#+NAME:board
#+RESULTS:
| | o | | | | | | |
| | | o | | | | | |
| o | o | o | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |