59 lines
2.2 KiB
Common Lisp
59 lines
2.2 KiB
Common Lisp
;; 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)))
|