Today’s input is a file with one string per line. Each line is an ID of a box.
(defvar *input-2*
(with-open-file (s "input/2.txt")
(loop for line = (read-line s nil :eof)
until (eq line :eof)
collect line)))
We need to count up the number of IDs which have one or more characters precisely twice and thrice. Multiplying these two together to generate our checksum.
The first thing I’ve done is generalize the original counting functions, so now there’s one that takes a parameter.
(defun count-np (string n)
(let ((chars (make-hash-table)))
(loop for c across string
if (gethash c chars)
do (incf (gethash c chars))
else
do (setf (gethash c chars) 1))
(loop for c being the hash-keys of chars
if (= (gethash c chars) n)
return t)))
(defun checksum (strings)
(* (loop for s in strings
count (count-np s 2))
(loop for s in strings
count (count-np s 3))))
<<count-2p>>
<<count-3p>>
<<count-np>>
<<checksum>>
(defun problem-2a () (format t "Problem 2b: ~a~%" (checksum *input-2*)))
The follow up problem is to find the pair of strings which are different by only one character. Go character by character on each pair of strings, kicking them out if more than two differ. If any pair are found that differ by just 1, return that immediately.
(defun find-boxes (strings)
(loop named outer
for s1 in strings
do (loop for s2 in strings
do (loop for c1 across s1
for c2 across s2
with diffs = 0
if (not (char= c1 c2))
do (incf diffs)
if (> diffs 1)
return nil
finally (if (= diffs 1) (return-from outer (list s1 s2)))))))
(defun problem-2b () (format t "Problem 2b:~%~{~a~%~}~%" (find-boxes *input-2*)))
<<day2-input>>
<<problem-2a>>
<<problem-2b>>
(problem-2a)
(problem-2b)
Problem 2b: 8892 Problem 2b: zihwtxagsifpbsnwleydukjmqv zihwtxagwifpbsnwleydukjmqv
I didn’t finish part 2 in code, I just printed both strings and examined them. Going to spend some time now cleaning these solutions up, I’m not happy with either.