Day 08 in Common Lisp

This commit is contained in:
aru 2021-12-08 18:22:35 +01:00
parent 69b0ec0568
commit 24189ff4c0
2 changed files with 79 additions and 0 deletions

10
08/example_input Normal file
View File

@ -0,0 +1,10 @@
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce

69
08/solution.lisp Normal file
View File

@ -0,0 +1,69 @@
(ql:quickload "split-sequence")
(ql:quickload "fset")
(defun read-data (path)
(with-open-file (stream path)
(loop for line = (read-line stream nil)
while line collect line)))
(defparameter *input-source*
(cadr *posix-argv*))
;; Useful in testing
(defparameter *input-source* "example_input")
(defparameter *input-source* "input")
(defun parse-line (line)
(split-sequence:split-sequence
(fset:set #\|) (mapcar (lambda (e) (fset:convert 'fset:set e)) (split-sequence:split-sequence #\Space line)) :test #'fset:equal?))
(defun parse-input (lines)
(map 'list #'parse-line lines))
(defparameter *data* (parse-input (read-data *input-source*)))
(defun part1 (input)
(loop for line in input
sum (loop for piece in (cadr line)
as l = (fset:size piece)
count (member l '(2 3 4 7)))))
(defun build-line-legend (line)
(let* ((sets (car line))
(eight (find-if (lambda (e) (= 7 (fset:size e))) sets))
(one (find-if (lambda (e) (= 2 (fset:size e))) sets))
(seven (find-if (lambda (e) (= 3 (fset:size e))) sets))
(four (find-if (lambda (e) (= 4 (fset:size e))) sets))
(three (find-if (lambda (e) (and (= 5 (fset:size e))
(fset:equal? (fset:intersection e seven) seven))) sets))
(nine (fset:union three four))
(two (find-if (lambda (e) (and (= 5 (fset:size e))
(fset:equal? (fset:union e four) eight))) sets))
(five (find-if (lambda (e) (and (= 5 (fset:size e))
(not (fset:equal? e two))
(not (fset:equal? e three)))) sets))
(six (fset:union five (fset:set-difference eight nine)))
(zero (find-if (lambda (e) (and (= 6 (fset:size e))
(not (fset:equal? e six))
(not (fset:equal? e nine)))) sets)))
(list zero one two three four five six seven eight nine)))
(defun digits-to-decimal (digits)
(loop with counter = 0
for digit in digits
do (setf counter (+ (* 10 counter) digit))
finally (return counter)))
(defun decode-number (legend line)
(digits-to-decimal (mapcar (lambda (e) (position e legend :test #'fset:equal?)) line)))
(defun part2 (input)
(loop for line in input
as legend = (build-line-legend line)
sum (decode-number legend (cadr line))))
(format t "===== Part 1 =====")
(format t "Result: ~A~%~%" (time (part1 *data*)))
(format t "===== Part 2 =====")
(format t "Result: ~A~%" (time (part2 *data*)))