Skip to content

Instantly share code, notes, and snippets.

@death
Created December 24, 2020 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save death/8dd5f03b41b517c19fdf41ecf20f0ac1 to your computer and use it in GitHub Desktop.
Save death/8dd5f03b41b517c19fdf41ecf20f0ac1 to your computer and use it in GitHub Desktop.
aoc2020 day24
;;;; +----------------------------------------------------------------+
;;;; | Advent of Code 2020 |
;;;; +----------------------------------------------------------------+
(defpackage #:snippets/aoc2020/day24
(:use #:cl)
(:export
#:day24))
(in-package #:snippets/aoc2020/day24)
(defun parse (input)
(mapcar #'parse-tile input))
(defun parse-tile (string)
(reduce #'+ (parse-path string)))
(defconstant east #C(+1 0))
(defconstant west #C(-1 0))
(defconstant southeast #C(+1/2 +1))
(defconstant southwest #C(-1/2 +1))
(defconstant northeast #C(+1/2 -1))
(defconstant northwest #C(-1/2 -1))
(defun parse-path (string)
(with-input-from-string (in string)
(loop for char = (read-char in nil nil)
while char
collect (ecase char
(#\e east)
(#\w west)
(#\s
(ecase (read-char in)
(#\e southeast)
(#\w southwest)))
(#\n
(ecase (read-char in)
(#\e northeast)
(#\w northwest)))))))
(defun flip (tiles)
(let ((tile-floor (make-hash-table)))
(dolist (tile tiles)
(if (gethash tile tile-floor)
(remhash tile tile-floor)
(setf (gethash tile tile-floor) t)))
tile-floor))
(defun num-black (tile-floor)
(hash-table-count tile-floor))
(defvar *directions*
(list east west southeast southwest northeast northwest))
(defun neighbor-counts (tile-floor)
(let ((counts (make-hash-table)))
(loop for black-tile being each hash-key of tile-floor
do (dolist (direction *directions*)
(incf (gethash (+ black-tile direction) counts 0))))
counts))
(defun day-flip (tile-floor)
(let ((new-tile-floor (make-hash-table))
(counts (neighbor-counts tile-floor)))
(loop for tile being each hash-key of counts
using (hash-value num-black)
when (if (gethash tile tile-floor)
(not (or (zerop num-black)
(> num-black 2)))
(= num-black 2))
do (setf (gethash tile new-tile-floor) t))
new-tile-floor))
(defun game-of-tiles (tile-floor n)
(if (plusp n)
(game-of-tiles (day-flip tile-floor) (1- n))
tile-floor))
(defun day24 (input)
(let ((tiles (parse input)))
(list (num-black (flip tiles))
(num-black (game-of-tiles (flip tiles) 100)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment