Half the problem of solving an Advent of Code puzzle is dealing with the puzzle input. It is generally in some ad hoc format that requires a bespoke parser. There are a few approches you can take.
- Read the input as a string and directly call string manipulation functions to extract the data.
- Read the input as a string and use regular expressions to extract the data.
- Use the lisp reader to read the input as a lisp data structure. This requires that the input looks like lisp objects.
- Tweak the Lisp reader to read the data in a custom format. This works if the input looks a lot like lisp objects.
For Day 1, the input is two columns of numbers. If we just scan
the file with the lisp reader, we'll get a single list of numbers.
We can convert this into two lists with the
series chunk
function:
(defun read-input (input-pathname) (multiple-value-bind (left-column right-column) (chunk 2 2 (scan-file input-pathname)) (values (collect ’list left-column) (collect ’list right-column))))
For part 1 of the puzzle, we sort both columns and then walk through them in parallel finding the absolute difference between the columns and summing that.
(defun part-1 () (multiple-value-bind (left-column right-column) (read-input (input-pathname)) (collect-sum (#Mabs (#M- (scan (sort left-column #’<)) (scan (sort right-column #’<)))))))
For part 2, we look at each number in the left column and multiply it by how many times it appears in the right column. We sum these quantities.
(defun part-2 () (multiple-value-bind (left-column right-column) (read-input (input-pathname)) (collect-sum (#M(lambda (item) (* item (count item right-column))) (scan left-column)))))
These examples show how we can use series and built-in sequence functions to eliminate loops.
No comments:
Post a Comment