-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday7.lisp
63 lines (55 loc) · 2.14 KB
/
day7.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
;;;; day7.lisp
(in-package :advent-of-code-2018)
(defun day7-parse-line (line)
(list (char line 5) (char line 36)))
(defun day7-build ()
(let ((counts (make-hash-table :test 'equal))
(links (make-hash-table :test 'equal)))
(loop-line-by-line (puzzlepath "input7.txt")
:for (before later) := (day9-parse-line line)
:do (push later (gethash before links nil))
:do (incf (gethash later counts 0))
:do (setf (gethash before counts) (gethash before counts 0))
:finally (return (list counts links)))))
(defun day7-next (counts)
(loop
:with next-key := nil
:for key :being :the :hash-keys :of counts
:when (and (or (null next-key)
(char< key next-key))
(= 0 (gethash key counts)))
:do (setf next-key key)
:finally (return next-key)))
(defun day7-task-time (letter)
(- (char-code (char-upcase letter)) 4)); #\A -> 65 - 4 -> 61
(defun day7-shortest-worker (w1 w2)
(if (< (first w1) (first w2))
w1
w2))
(defun day7-solve (&optional (worker-count 5))
(destructuring-bind (counts links) (day9-build)
(loop
:with seq := nil
:with workers := nil
:with time := 0
:for next := (day9-next counts)
:while (or workers next)
:when (or (= (length workers) worker-count)
(null next))
:do (let ((earliest (reduce #'day9-shortest-worker workers)))
(setf workers (remove earliest workers))
(dolist (child (gethash (cdr earliest) links))
(decf (gethash child counts)))
(push (cdr earliest) seq)
(setf time (car earliest)))
:when next
:do (push (cons (+ time (day9-task-time next)) next) workers)
:and :do (remhash next counts)
:finally (return (list (coerce (nreverse seq) 'string) time)))))
(defun day7 ()
(destructuring-bind (seq time) (day9-solve 1)
(format t "With 1 worker the tasks are completed in this order: ~a and take ~a seconds.~%"
seq time))
(destructuring-bind (seq time) (day9-solve 5)
(format t "With 5 workers the tasks are completed in this order: ~a and take ~a seconds.~%"
seq time)))