blob: 27f08f302d8de166c7dec09f4fdff1e7f7d3879b (
plain)
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
53
54
55
56
57
58
59
60
61
62
|
;;;; aoc-2022-3.lisp
(defpackage #:aoc/2022/3
(:use #:cl))
(in-package #:aoc/2022/3)
(defun priority (ch)
"Priority as defined in the problem text: a -> z is 0 -> 26, A -> Z is 27 -> 52."
(declare (type character ch))
(if (upper-case-p ch)
(+ 27 (- (char-code ch) (char-code #\A)))
(1+ (- (char-code ch) (char-code #\a)))))
(defun string-sort (str)
(sort
(delete-duplicates str) #'char<))
(defun line-priority (line)
"Find common characters between the two halves of LINE and return the
sum of their priorities."
(declare (type string line))
(let* ((half (/ (length line) 2))
(left (string-sort (subseq line 0 half)))
(right (string-sort (subseq line half)))
(prio 0))
(loop :for c :across left
:if (find c right)
:do (incf prio (priority c)))
prio))
(defun badge (lines)
"Find the common element between the three LINES and return its priority."
(declare (type list lines))
(loop :for line :in lines
:do (setf line (string-sort line)))
(loop :for c :across (first lines)
:if (and (find c (second lines))
(find c (third lines)))
:return (priority c)))
(defun read-n-lines (n &optional (stream *standard-input*))
"Read N lines from STREAM, or from *STANDARD-INPUT*."
(declare (type fixnum n))
(handler-case
(loop :for i :to (1- n)
:collect (read-line stream nil))
(error ()
nil)))
(defun part2 ()
"For some reason this errors on EOF. Solved it by summing the printed values."
(with-open-file (stream "input-3")
(let ((prio 0))
(do ((lines (read-n-lines 3 stream nil)
(read-n-lines 3 stream nil)))
((or (null lines)
(find nil lines))
prio)
(let ((b (badge lines)))
(format t "~a~%" b)
(incf prio b))))))
|