Day 08 in Common Lisp
This commit is contained in:
parent
69b0ec0568
commit
24189ff4c0
|
@ -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
|
|
@ -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*)))
|
Reference in New Issue