diff options
Diffstat (limited to 'src/03.lisp')
-rw-r--r-- | src/03.lisp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/03.lisp b/src/03.lisp new file mode 100644 index 0000000..ae2f0bd --- /dev/null +++ b/src/03.lisp @@ -0,0 +1,45 @@ +(load "~/quicklisp/setup.lisp") +(ql:quickload "uiop") + +(defun get-file-lines (name) + (uiop:read-file-lines name)) + +(defun parse-bin-char (x) (case x (#\1 1) (#\0 0))) + +;; Turn the input file into whatever form you will use for both parts +;; (get-file-lines) and (get-file-string) will be useful +(defun parse-input (input-file) + (mapcar (lambda (x) (mapcar #'parse-bin-char (coerce x 'list))) (get-file-lines input-file))) + +;; Loops through two item windows on input and counts each time the first is less than the second +(defun partial (func &rest args1) + (lambda (&rest args2) + (apply func (append args1 args2)))) + +(defun is-less (h l) + (mapcar (lambda (x) (if (< x h) 0 1)) l)) + +(defun not-list (l) + (mapcar (lambda (x) (if (= x 0) 1 0)) l)) + +(defun range (max &key (min 0) (step 1)) + (loop :for n :from (- max 1) :above (- min 1) :by step + :collect n)) + +(defun to-dec (l) + (apply #'+ (mapcar (lambda (a b) (* a (expt 2 b))) l (range (list-length l))))) + +(defun part-a (parsed-input) + (let* ((half-length (/ (list-length parsed-input) 2)) + (l (is-less half-length (apply (partial #'mapcar #'+) parsed-input))) + (gamma (to-dec l)) + (epsilon (to-dec (not-list l)))) + (* epsilon gamma))) + +;; Similar to part a, but with four item windows, comparing the sum of the first 3 with the next 3 +(defun part-b (parsed-input) + (loop for (w x y z) on parsed-input until (null z) if (< (+ w x y) (+ x y z)) count w)) + +(time (format t "part 1: ~a~%" (part-a (parse-input "../inputs/03.txt")))) +;;(time (format t "part 1: ~a~%" (part-a (parse-input "test.txt")))) +;;(time (format t "part 1: ~a~%" (part-b (parse-input "../inputs/01.txt")))) |