-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday7.lsp
201 lines (178 loc) · 6.45 KB
/
day7.lsp
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
;; Day7
;;
(defvar pwd nil)
(setf pwd nil)
(defvar root nil)
(setf root nil)
(defvar prev nil)
(setf prev nil)
(defvar cur nil)
(setf cur nil)
(defvar *totals* nil)
(setf *totals* nil)
(defvar part1-limit 100000)
(defun add-value (key value alist)
(acons key value alist))
(defun get-value (key alist)
(cdr (assoc key alist :test #'equal)))
(defun update-value (key value alist)
(setf (cdr (assoc key alist :test #'equal)) value))
(defun new-pwd (dir-name)
(setf *totals* (add-value dir-name 0 *totals*))
(list (cons "dir" dir-name)))
(defun total-key (postfix)
(concatenate 'string "total" "-" postfix))
(defun new-dir (prev cur)
; just concatenates two strings. Less verbose
(concatenate 'string prev "-" cur))
(defun get-prev-from-cur (cur)
; get the parent alist from cur string
(let ((prev (subseq cur 0 (position #\- cur :from-end 't))))
(if (equal "/" prev)
(return-from get-prev-from-cur root)
(get-value prev (get-prev-from-cur prev))
)))
(defun update-prev-alist (pwd cur new-total &optional final)
; probably recursive, doesn't actually update?
; returns current alist inserted into it's position in the previous alist
; updates totals as it goes
(let ((parent (get-prev-from-cur cur))
(prev (subseq cur 0 (position #\- cur :from-end 't))))
(when (equal "/" cur) ; no parent means cur is the root
(setf root pwd)
(return-from update-prev-alist))
(update-value cur pwd parent)
(when (< 0 new-total)
(update-value (total-key prev) (+
;(get-value (total-key cur) pwd)
new-total
(get-value (total-key prev) parent))
parent)
;(format t "Added total of ~a to ~a~%" cur prev)
)
;(format t "Total ~d assigned to ~a~%" (get-value (total-key prev) parent) prev)
(update-value prev (get-value (total-key prev) parent) *totals*)
(unless (equal "/" prev)
(if final
(update-prev-alist parent prev new-total final)
(update-prev-alist parent prev 0)))))
(ql:quickload :cl-ppcre )
(defun load-file (filename)
(with-open-file (in filename)
(loop for line = (read-line in nil)
while line
collect line)))
(defvar *file* nil) ;;procedure
(setf *file* (load-file "day7_input.txt")) ;; procedure
;(setf *file* (load-file "./test_input_day7.txt")) ;; procedure
;; (defvar pwd nil)
;; (setf pwd nil)
;; (defvar root nil)
;; (setf root nil)
;; (defvar prev nil)
;; (setf prev nil)
;; (defvar cur nil)
;; (setf cur nil)
(defun get-totals (file-list)
(let (split-line
filesize
(new-files nil)
(new-total 0))
;(format t "Begin File Read")
(dolist (line file-list)
;(format t "File Line: ~a~%" line)
(setf split-line (cl-ppcre:split :whitespace-char-class line))
(cond
((equal "$" (first split-line))
(cond
((equal "cd" (second split-line))
(cond
((equal ".." (third split-line))
;(format t "Reached $ cd ..~%")
;(when new-files
(update-prev-alist pwd cur (get-value (total-key cur) pwd))
;)
(setf pwd (get-prev-from-cur cur))
(setf cur (get-value "dir" pwd))
;; (unless new-files
;; (update-prev-alist pwd cur (get-value (total-key cur) pwd)))
(setf new-files nil)
)
((equal "/" (third split-line))
;(format t "Reached $ cd /~%")
(setf cur "/")
(setf pwd (new-pwd cur)))
('t
;(format t "Reached $ cd ~a~%" (third split-line))
;(update-prev-alist pwd cur (get-value (total-key cur) pwd))
(update-prev-alist pwd cur 0)
(setf prev cur)
(setf cur (new-dir prev (third split-line)))
(setf pwd (new-pwd cur)))))
('t
; only other option is ls
;(format t "Reached $ ls~%")
(setf new-files 't)
(setf pwd (add-value (total-key cur) 0 pwd)))))
((equal "dir" (first split-line))
;(format t "Reached dir ~a~%" (second split-line))
(setf pwd (add-value (new-dir cur (second split-line)) nil pwd)))
('t
; only other option is file
;(format t "Reached ~a ~a~%" (first split-line) (second split-line))
(setf filesize (parse-integer (first split-line)))
(setf pwd (add-value (second split-line) filesize pwd))
(update-value (total-key cur) (+ filesize (get-value (total-key cur) pwd)) pwd)
(update-value cur (get-value (total-key cur) pwd) *totals*)
;(format t "total ~d assigned to ~a~%" (get-value (total-key cur) pwd) cur)
))
)
; finally, save final directory
; loop to push the changes
(update-prev-alist pwd cur (get-value (total-key cur) pwd) 't)))
(get-totals *file*) ; procedure
(defun count-totals (totals limit)
(let ((running-count 0))
(dolist (next totals)
(when (>= limit (cdr next))
(setf running-count (+ running-count (cdr next)))))
running-count))
(format t "Day7 Part1: ~d~%" (count-totals *totals* part1-limit))
(defun get-free-space (totals)
(let* ((disk-size 70000000)
(space-needed 30000000)
(unused (- disk-size (get-value "/" totals)))
(target (- space-needed unused))
(next-size 0)
(running-min disk-size))
;(format t "unused: ~d~%" unused)
;(format t "target: ~d~%" target)
(dolist (next totals)
(setf next-size (cdr next))
(when (and
(<= target next-size )
(>= running-min next-size))
(setf running-min next-size)))
running-min))
(defun sum-alist (alist)
(let ((running-total 0)
(cur ""))
(dolist (next alist)
(cond
((listp (cdr next))
(setf running-total
(+ running-total
(sum-alist (cdr next)))))
((integerp (cdr next))
(unless (position #\/ (car next))
(setf running-total
(+ running-total
(cdr next)))))
((equal "dir" (car next))
(setf cur (cdr next)))))
;(format t "Total for ~a: ~d~%" cur running-total)
(update-value cur running-total *totals*)
running-total))
(sum-alist root) ;procedure
;
(format t "Day7 Part2: ~d~%" (get-free-space *totals*))