Skip to content

Instantly share code, notes, and snippets.

@death
Created December 10, 2021 06:16
aoc2021 day10
;;;; +----------------------------------------------------------------+
;;;; | Advent of Code 2021 |
;;;; +----------------------------------------------------------------+
(defpackage #:snippets/aoc2021/day10
(:use #:cl)
(:export
#:day10))
(in-package #:snippets/aoc2021/day10)
(defvar *pairings*
'((#\( #\) 3)
(#\[ #\] 57)
(#\{ #\} 1197)
(#\< #\> 25137)))
(defun closing-char (char)
(second (find char *pairings* :key #'first)))
(defun char-error-score (char)
(third (find char *pairings* :key #'second)))
(defun char-completion-score (char)
(1+ (or (position char *pairings* :key #'second)
(error "~S is not a closing character." char))))
(defun add-char-completion-score (score char)
(+ (* 5 score) (char-completion-score char)))
(defun string-completion-score (chars)
(reduce #'add-char-completion-score chars :initial-value 0))
(defun check (line)
(let ((stack '())
(closing nil))
(loop for char across line
do (cond ((setq closing (closing-char char))
(push closing stack))
((eql char (car stack))
(pop stack))
(t
(return-from check (list :corrupted (char-error-score char))))))
(list :incomplete (string-completion-score stack))))
(defun take-middle (sequence)
(let ((n (length sequence)))
(elt (sort sequence #'<) (truncate n 2))))
(defun scores (type-of-interest errors)
(loop for (type score) in errors
when (eq type type-of-interest)
collect score))
(defun day10 (input)
(let ((errors (mapcar #'check input)))
(list (reduce #'+ (scores :corrupted errors))
(take-middle (scores :incomplete errors)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment