aboutsummaryrefslogtreecommitdiff
path: root/2022/3.lisp
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))))))