Advent Of Code '23 - day 02

Table of Contents

This took me way too long. After struggling for hours with regexps in elisp I decided to stop using them completely and just do some string splitting instead. Part 2 was solved quickly as I could reuse the same datamodel from part 1.

Inputs

Example

Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green

Part 1

(defun aoc23/line-to-tuples (line)
  (if (length= line 0) '()
    (let* ((game-id (string-to-number (cadr (string-split (car (string-split line ":"))))))
           (rest (cadr (string-split line ":")))                    
           (tuples `(,game-id))
           (highest-red 0)
           (highest-green 0)
           (highest-blue 0)
           (n 0)
           (o 0))

      (dolist (p (string-split rest ";"))
        (dolist (pp (string-split p ","))
          (let* ((ppp (string-split pp))
               (n (string-to-number (car ppp)))
               (color (cadr ppp)))
            (cond ((string= "red" color)
                   (when (> n highest-red)
                     (setq highest-red n)))
                  ((string= "green" color)
                   (when (> n highest-green)
                     (setq highest-green n)))
                  ((string= "blue" color)
                   (when (> n highest-blue)
                     (setq highest-blue n))))
          )))


      (setq tuples (append tuples `(
        (:highest-red . ,highest-red)
        (:highest-green . ,highest-green)
        (:highest-blue . ,highest-blue))))
      )))

(defun aoc23/pass-test-1 (tuple)
  (and (length> tuple 0)
       (<= (alist-get :highest-red tuple) 12)
       (<= (alist-get :highest-green tuple) 13)
       (<= (alist-get :highest-blue tuple) 14)))


(apply '+
       (mapcar 'car
               (seq-filter 'aoc23/pass-test-1
                           (mapcar 'aoc23/line-to-tuples
                                   (string-split input "\n")))))

Part 2

(defun aoc23/line-to-tuples (line)
  (if (length= line 0) '()
    (let* ((game-id (string-to-number (cadr (string-split (car (string-split line ":"))))))
           (rest (cadr (string-split line ":")))                    
           (tuples `(,game-id))
           (highest-red 0)
           (highest-green 0)
           (highest-blue 0)
           (n 0)
           (o 0))

      (dolist (p (string-split rest ";"))
        (dolist (pp (string-split p ","))
          (let* ((ppp (string-split pp))
               (n (string-to-number (car ppp)))
               (color (cadr ppp)))
            (cond ((string= "red" color)
                   (when (> n highest-red)
                     (setq highest-red n)))
                  ((string= "green" color)
                   (when (> n highest-green)
                     (setq highest-green n)))
                  ((string= "blue" color)
                   (when (> n highest-blue)
                     (setq highest-blue n))))
          )))


      (setq tuples (append tuples `(
        (:highest-red . ,highest-red)
        (:highest-green . ,highest-green)
        (:highest-blue . ,highest-blue))))
      )))

(defun aoc23/calc-test-2 (tuple)
  (apply '* `(,(alist-get :highest-red tuple)
              ,(alist-get :highest-green tuple)
              ,(alist-get :highest-blue tuple))))



(apply '+
       (mapcar 'aoc23/calc-test-2
               (seq-filter (lambda (tup) tup)
                           (mapcar 'aoc23/line-to-tuples
                                   (string-split input "\n")))))