;; https://github.com/kraison/graph-utils (ql:quickload 'graph-utils) (ql:quickload 'alexandria) ;;; reading in data ;; graph and hashmap from node name to flow and state (defclass verticle-data () ((flow :reader flow :initarg :flow) (name :reader name :initarg :name) (is-opened-p :accessor is-opened-p :initform t))) (defmethod print-object ((obj verticle-data) stream) (with-slots (name flow is-opened-p) obj (format stream "~a with flow: ~a; is opened? ~a" name flow is-opened-p))) (defun parse-integer-or-symbol (str) (let ((maybe-int (parse-integer str :junk-allowed t))) (if maybe-int maybe-int (intern (string-upcase str))))) (defun parse-input-line (line) (destructuring-bind (-valve source-name -has -flow -rate flow-rate -tunnels -lead -to -valves &rest to-valve-names) (mapcar #'parse-integer-or-symbol (remove-if (lambda (str) (equal "" str)) (cl-ppcre:split "(,| |=)" line))) (format t "from ~a with ~a; to ~a~%" source-name flow-rate to-valve-names) (list source-name flow-rate to-valve-names))) (defun read-file-data (filename graph vertices-data-map) (loop for line-struct in (mapcar #'parse-input-line (uiop:read-file-lines filename)) do (put-struct-into-storages line-struct graph vertices-data-map))) ;;; calculations for part 1 (defun get-possible-next-vs (cur-node graph vertices-data-map shortest-paths time-remaining) (loop for (from . to) being the hash-keys in shortest-paths using (hash-value dist) for from-node = (graph-utils:lookup-node graph from) for to-node = (graph-utils:lookup-node graph to) for to-node-data = (gethash to-node vertices-data-map) when (and (equal cur-node from-node) (not (equal cur-node to-node)) (not (= 0 (flow to-node-data))) (> time-remaining dist) (is-opened-p to-node-data)) do (format t "from ~a to ~a dist: ~a. ~a~%" from-node to-node dist to-node-data) when (and (equal cur-node from-node) (not (equal cur-node to-node)) (not (= 0 (flow to-node-data))) (> time-remaining dist) (is-opened-p to-node-data)) collect (list to-node dist)))