/
day05.lisp
52 lines (42 loc) · 1.56 KB
/
day05.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
(mgl-pax:define-package :aoc.2020.05
(:nicknames :2020.05)
(:use :cl :aoc.util :mgl-pax)
(:export #:decode #:highest-seat-id))
(in-package :2020.05)
(defsummary (:title "Binary Boarding")
"**Part 1** - Binary Seat Encoding"
(highest-seat-id function)
"**Part 2** - Find the unoccupied seat"
(find-open-seat function))
(defun build-data (&optional input)
(read-day-input #'identity :input input))
(defun decode-bits (string &key (ones #\B))
(loop with sum = 0
for char across string
for index = (length string) then (1- index)
when (char= char ones)
do (incf sum (expt 2 (1- index)))
finally (return sum)))
(defun decode (boarding-pass)
(let ((row (decode-bits (subseq boarding-pass 0 7)))
(seat (decode-bits (subseq boarding-pass 7) :ones #\R)))
(values row seat)))
(defun seat-id (pass)
(multiple-value-bind (row seat) (decode pass)
(+ (* row 8) seat)))
(defun highest-seat-id (passes)
(loop for pass in passes maximizing (seat-id pass)))
(defun part-1 (&optional (data (build-data)))
(highest-seat-id data))
(defun find-open-seat (passes)
(let ((table (make-hash-table)))
(dolist (pass passes)
(let ((seat (seat-id pass)))
(setf (gethash seat table) seat)))
(loop for seat-id = 0 then (1+ seat-id)
when (and (gethash (1- seat-id) table)
(not (gethash seat-id table))
(gethash (1+ seat-id) table))
do (return-from find-open-seat seat-id))))
(defun part-2 (&optional (data (build-data)))
(find-open-seat data))