aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/13/solver.el
blob: 3039c1efa25438db7aef9b5d52f885b27780a5c5 (plain)
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
;;; solver.el --- DAy 13 -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 Óscar Nájera
;;
;; Author: Óscar Nájera <hi@oscarnajera.com>
;; Maintainer: Óscar Nájera <hi@oscarnajera.com>
;; Created: December 13, 2022
;; Modified: December 13, 2022
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;;  DAy 13
;;
;;; Code:

(defun solver-input (filename &optional prepend)
  (with-temp-buffer
    (when prepend
      (insert "[[2]]\n[[6]]\n"))
    (insert-file-contents filename)
    (goto-char (point-min))
    (cl-loop
     for a = (ignore-errors
               (list
                (json-parse-buffer :array-type 'list)
                (json-parse-buffer :array-type 'list)))
     while a
     nconc a)))

(defun solver-compare (f s)
  (cond
   ((eq f s) 'next)
   ((and (null f) (not (null s))) t)
   ((and (not (null f)) (null s)) nil)
   ((and (integerp f) (integerp s)) (< f s))
   ((and (integerp f) (consp s)) (solver-compare (list f) s))
   ((and (consp f) (integerp s)) (solver-compare f (list s)))
   ((let ((result (solver-compare (car f) (car s))))
      (if (eq result 'next) (solver-compare (cdr f) (cdr s))
        result)))))

(ert-deftest test-comparison ()
  (should (eq (solver-compare 5 5) 'next))
  (should (eq (solver-compare nil nil) 'next))
  (should-not (solver-compare 5 nil))
  (should (solver-compare nil 5))
  (should (eq (solver-compare '(9) '((8 7))) nil))
  (should (solver-compare '(1 1 3 1 1) '(1 1 5 1 1)))
  (should (solver-compare '((1) (2 3 4)) '((1) 4)))
  (should (solver-compare '() '(5))))


(defun solver-p1 (filename)
  (cl-loop
   for i from 1
   for (a b) on (solver-input filename) by #'cddr
   when (solver-compare a b)
   sum i))

(ert-deftest test-1 ()
  (should (= 13 (solver-p1 "eg-in")))
  (should (= 5330 (solver-p1 "input"))))

(defun solver-p2 (filename)
  (let ((sorted-packets (cl-sort (solver-input filename t) #'solver-compare)))
    (cl-flet ((pick (item)
                    (1+ (cl-position
                         (cl-ecase item
                           ('start '((2)))
                           ('end '((6))))
                         sorted-packets :test #'equal))))
      (* (pick 'start) (pick 'end)))))

(ert-deftest test-2 ()
  (should (= 140 (solver-p2 "eg-in")))
  (should (= 27648 (solver-p2 "input"))))