summaryrefslogtreecommitdiffstats
path: root/day04.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'day04.lisp')
-rw-r--r--day04.lisp53
1 files changed, 53 insertions, 0 deletions
diff --git a/day04.lisp b/day04.lisp
new file mode 100644
index 0000000..8505c53
--- /dev/null
+++ b/day04.lisp
@@ -0,0 +1,53 @@
+(defun input-lines (f)
+ (with-open-file (s f)
+ (loop for line = (read-line s nil 'eof)
+ until (eq line 'eof)
+ collect line)))
+
+(defun split-by-char (char string)
+ (loop for i = 0 then (1+ j)
+ as j = (position char string :start i)
+ collect (subseq string i j)
+ while j))
+
+(defun parse-integers (string)
+ (loop for i = 0 then (cadr o)
+ as o = (multiple-value-list (parse-integer string :start i :junk-allowed t))
+ as n = (car o)
+ while n
+ collect n))
+
+(defun card-winning (winning numbers)
+ (loop for number in numbers
+ count (member number winning)))
+
+(defun line-winning (line)
+ (let ((card-info (split-by-char #\| (cadr (split-by-char #\: line)))))
+ (let ((winning (parse-integers (car card-info)))
+ (numbers (parse-integers (cadr card-info))))
+ (card-winning winning numbers))))
+
+(defun line-points (line)
+ (ash 1 (1- (line-winning line))))
+
+(defun solve1 (f)
+ (let ((lines (input-lines f)))
+ (reduce #'+ (mapcar 'line-points lines))))
+
+(defun solve2 (f)
+ (let ((lines (input-lines f)))
+ (let ((arr (make-array (length lines) :initial-element 1)))
+ (loop for i = 0 then (1+ i)
+ for line in lines
+ as count = (line-winning line)
+ as v = (aref arr i)
+ do (loop for j from 1 to count
+ as e = (aref arr (+ i j))
+ do (setf (aref arr (+ i j)) (+ v e)))
+ sum v))))
+
+(print (solve1 "data/04/example.txt")) ;; 13
+(print (solve1 "data/04/input.txt")) ;; 24160
+(print (solve2 "data/04/example.txt")) ;; 30
+(print (solve2 "data/04/input.txt")) ;; 5659035
+