adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

day13.lisp (1928B)


      1 (defpackage #:adventofcode2022/day13
      2   (:use #:cl #:adventofcode2022 #:binding-arrows))
      3 (in-package #:adventofcode2022/day13)
      4 
      5 (defun compare-lists (a b)
      6   (cond
      7     ((and (null a) (null b))
      8      :continue)
      9     ((null a)
     10      t)
     11     ((null b)
     12      nil)
     13     ((and (vectorp a) (not (vectorp b)))
     14      (compare-lists a (vector b)))
     15     ((and (not (vectorp a)) (vectorp b))
     16      (compare-lists (vector a) b))
     17     ((and (numberp a) (numberp b))
     18      (if (= a b)
     19          :continue
     20          (< a b)))
     21     (t (loop for ia from 0
     22              for ib from 0
     23              for va = (if (< ia (length a)) (aref a ia) nil)
     24              for vb = (if (< ib (length b)) (aref b ib) nil)
     25              for res = (compare-lists va vb)
     26              when (not (eq res :continue))
     27                return res
     28              when (and (null va) (null vb))
     29                return :continue
     30              finally (return t)))))
     31 
     32 (defun task1 (inputs)
     33   (loop with inputs = (remove-if #'null inputs)
     34         for a = (pop inputs)
     35         for b = (pop inputs)
     36         for i from 1
     37         while a
     38         when (compare-lists a b)
     39           sum i))
     40 
     41 (defun task2 (inputs)
     42   (let ((divider-packets (list #(#(2)) #(#(6)))))
     43     (apply #'*
     44            (loop for packet in (-> (remove-if #'null inputs)
     45                                  (append (copy-seq divider-packets))
     46                                  (sort #'compare-lists))
     47                  for i from 1
     48                  when (find packet divider-packets :test 'eq)
     49                    collect i))))
     50 
     51 (define-day 13
     52     (:translate-input (lambda (line)
     53                         (if (= (length line) 0)
     54                             nil
     55                             (->> line
     56                               (str:replace-all "[" "#(")
     57                               (str:replace-all "]" ")")
     58                               (str:replace-all "," " ")
     59                               (read-from-string)))))
     60   #'task1
     61   #'task2)