summaryrefslogtreecommitdiffstats
path: root/day02.lisp
blob: c007a9f77466874580a0d2b7fb49d901aa42e9df (plain) (blame)
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
(defun input-lines (f)
  (with-open-file (s f)
    (loop for line = (read-line s nil 'eof)
          until (eq line 'eof)
          collect line)))

(defun check-set (string red green blue)
  (multiple-value-bind (n begin)
      (parse-integer string :junk-allowed t)
    (cond ((search "red" string :start2 begin) (<= n red))
          ((search "green" string :start2 begin) (<= n green))
          ((search "blue" string :start2 begin) (<= n blue)))))

(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 check-round (string red green blue)
  (let ((sets (split-by-char #\, string)))
    (not (find-if-not (lambda (set) (check-set set red green blue)) sets))))

(defun check-game (string red green blue)
  (let ((pstring (nth 1 (split-by-char #\: string))))
    (let ((rounds (split-by-char #\; pstring)))
      (not (find-if-not (lambda (set) (check-round set red green blue)) rounds)))))

(defun solve1 (f)
  (loop for line in (input-lines f)
        as gid = (parse-integer line :junk-allowed t :start 5)
        when (check-game line 12 13 14)
          sum gid))

(defun cube-count (string color)
  (multiple-value-bind (n begin)
      (parse-integer string :junk-allowed t)
    (if (search color string :start2 begin) n 0)))

(defun game-max-cubes (line color)
  (loop for i = (1+ (position #\: line)) then (1+ j)
        as j = (position-if (lambda (c) (or (equal c #\,) (equal c #\;))) line :start i)
        as count = (cube-count (subseq line i j) color)
        maximize count
        while j))

(defun solve2 (f)
  (loop for line in (input-lines f)
        as r = (game-max-cubes line "red")
        as g = (game-max-cubes line "green")
        as b = (game-max-cubes line "blue")
        sum (* r g b)))

(print (solve1 "data/02/example.txt"))
(print (solve1 "data/02/input.txt"))
(print (solve2 "data/02/example.txt"))
(print (solve2 "data/02/input.txt"))