;;; solver.el --- DAy 13 -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2022 Óscar Nájera ;; ;; Author: Óscar Nájera ;; Maintainer: Óscar Nájera ;; 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"))))