diff --git a/03/example_input b/03/example_input new file mode 100644 index 0000000..a6366a8 --- /dev/null +++ b/03/example_input @@ -0,0 +1,12 @@ +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 diff --git a/03/solution.lisp b/03/solution.lisp new file mode 100644 index 0000000..f993977 --- /dev/null +++ b/03/solution.lisp @@ -0,0 +1,60 @@ +(defun read-data (path) + (with-open-file (stream path) + (loop for line = (read-line stream nil) + while line collect line))) + +(defparameter *input-source* + (cadr *posix-argv*)) + +;; Useful in testing +;; (defparameter *input-source* "example_input") +;; (defparameter *input-source* "input") + +(defparameter *data* + (coerce (read-data *input-source*) 'vector)) + +(defun most-common (data column) + (loop for row across data + counting (char= #\0 (aref row column)) into zeroes + counting (char= #\1 (aref row column)) into ones + finally (return (if (> zeroes ones) #\0 #\1)))) + +(defun least-common (data column) + (invert-bit (most-common data column))) + +(defun invert-bit (bit) + (if (char= bit #\0) #\1 #\0)) + +(defun invert (bits) + (map 'string #'invert-bit bits)) + +(defun gamma-rate (data) + (loop for column from 0 below (length (aref data 0)) + collect (most-common data column))) + +(defun parse-bitfield (bits) + (parse-integer (coerce bits 'string) :radix 2)) + +(defun part1 (data) + (let ((gamma-bits (gamma-rate data))) + (* (parse-bitfield gamma-bits) + (parse-bitfield (invert gamma-bits))))) + +(defun with-bit-at-position (data position bit) + (remove-if-not (lambda (row) (char= (aref row position) bit)) + data)) + +(defun part2-filter (data &key (most-common-f #'most-common)) + (loop for d = data then (with-bit-at-position d column (funcall most-common-f d column)) + for column from 0 below (length (aref data 0)) + until (= 1 (length d)) + finally (return (aref d 0)))) + +(defun part2 (data) + (let ((oxygen (part2-filter data)) + (co2 (part2-filter data :most-common-f #'least-common))) + (* (parse-bitfield oxygen) + (parse-bitfield co2)))) + +(format t "Part 1: ~A~%" (part1 *data*)) +(format t "Part 2: ~A~%" (part2 *data*))