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))))