;;; solver.el --- Day 03 -*- lexical-binding: t; -*- ;; ;; Copyright (C) 2022 Óscar Nájera ;; ;; Author: Óscar Nájera ;; Maintainer: Óscar Nájera ;; Created: December 04, 2022 ;; Modified: December 04, 2022 ;; ;; This file is not part of GNU Emacs. ;; ;;; Commentary: ;; ;; Day 03 ;; ;;; Code: (require 'subr-x) (defsubst solver-recover-value (cross) (let ((result 0)) (while (= 0 (logand cross 1)) (setq cross (ash cross -1)) (cl-incf result)) result)) (ert-deftest test-recover () (should (eq ?t (+ 64 (solver-recover-value (ash 1 (- ?t 64)))))) (should (eq ?s (+ 64 (solver-recover-value (ash 1 (- ?s 64)))))) (should (eq ?C (+ 64 (solver-recover-value (ash 1 (- ?C 64))))))) ;; small cap starts at a=97, but already took 64 (defsubst solver-to-priority (value) (if (< value 31) ;; It is a capital letter in range [1;26] (+ value 26) (- value 32))) (defun solver-line-priority (str) (cl-assert (length> str 0)) (let ((mid (/ (length str) 2)) (left-pack 0) (right-pack 0)) (cl-loop for l across (substring str 0 mid) for r across (substring str mid) do (progn (setf left-pack (logior left-pack (ash 1 (- l 64)))) ;; ASCII letters start at 65=A (setf right-pack (logior right-pack(ash 1 (- r 64))))) for cross = (logand left-pack right-pack) when (< 0 cross) return (solver-to-priority (solver-recover-value cross))))) (ert-deftest test-line-priority () (should (= 16 (solver-line-priority "vJrwpWtwJgWrhcsFMMfFFhFp"))) (should (= 19 (solver-line-priority "hMHLcmGLMLhHmsRMsSvsQSqrsrlJTTdV" ))) (should (= 20 (solver-line-priority "ttgJtRGJQctTZtZT")))) (defsubst solver-badge (packs) (seq-reduce (lambda (acc item) (logior acc (ash 1 (- item 64)))) packs 0)) (defun solver-badge-priority (group-packs) (thread-last group-packs (split-string) (mapcar #'solver-badge) (apply #'logand) (solver-recover-value) (solver-to-priority))) (defun solver (task lines) (with-temp-buffer (insert-file-contents "input") (goto-char (point-min)) (cl-loop while (not (eobp)) sum (funcall task (buffer-substring-no-properties (point) (line-end-position lines))) do (forward-line lines)))) (ert-deftest test-problems () (should (= 8072 (solver #'solver-line-priority 1))) (should (= 2567 (solver #'solver-badge-priority 3))))