adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

main.lisp (1648B)


      1 (defpackage #:adventofcode2022
      2   (:use #:cl)
      3   (:export
      4    #:run-task
      5    #:add-task
      6    #:define-day))
      7 (in-package #:adventofcode2022)
      8 
      9 (defparameter *days* (make-hash-table))
     10 
     11 (defun add-task (day task func)
     12   (let ((current (gethash day *days*)))
     13     (when (null current)
     14       (setf current (make-array 2)))
     15     (setf (aref current (1- task)) func)
     16     (setf (gethash day *days*) current)))
     17 
     18 (defun run-task (day task &optional input-stream)
     19   (let* ((tasks (gethash day *days*))
     20          (taskfun (aref tasks (1- task)))
     21          (s (if (null input-stream)
     22                 (open
     23                  (merge-pathnames
     24                   (make-pathname
     25                    :directory '(:relative "input")
     26                    :name (format nil "day~2,'0d" day)
     27                    :type "txt")
     28                   (asdf:system-source-directory "adventofcode2022")))
     29                 input-stream)))
     30     (unwind-protect
     31          (funcall taskfun s)
     32       (close s))))
     33 
     34 (defun parse-input (input-stream opts)
     35   (let ((translate-fun (getf opts :translate-input))
     36         (lines (uiop:slurp-stream-lines input-stream)))
     37     (when (not (null translate-fun))
     38       (setf lines (mapcar translate-fun lines)))
     39     lines))
     40 
     41 (eval-when (:compile-toplevel)
     42   (defun make-add-task-form (day task opts form)
     43     `(add-task ,day ,task
     44                (lambda (input-stream)
     45                  (let ((inputs (parse-input input-stream (list ,@opts))))
     46                    (funcall ,form inputs))))))
     47 
     48 (defmacro define-day (day opts task1 task2)
     49   `(progn
     50      ,(make-add-task-form day 1 opts task1)
     51      ,(when (not (null task2))
     52         (make-add-task-form day 2 opts task2))))