;; // https://adventofcode.com/2022/day/21 (defpackage :day-21 (:use :cl)) (in-package :day-21) (ql:quickload 'cl-ppcre) (defun parse-integer-or-symbol (str) (let ((maybe-int (parse-integer str :junk-allowed t))) (if maybe-int maybe-int (intern (string-upcase str))))) (defun line-to-quoted-operation (line) (let* ((words (ppcre:split " " (ppcre:regex-replace ":" line ""))) (symbols (mapcar #'parse-integer-or-symbol words))) (cond ((= 4 (length symbols)) ;; with operation (destructuring-bind (name operand1 op operand2) symbols `(defparameter ,name '(,op (eval ,operand1) (eval ,operand2))))) ((= 2 (length symbols)) ;; just number (destructuring-bind (name value) symbols `(defparameter ,name ,value)))))) (defun load-file-defs (filename) (loop for line in (uiop:read-file-lines filename) for definition = (line-to-quoted-operation line) do (eval definition))) (defun reverse-operation (op) (case op ('* '/) ('/ '*) ('+ '-) ('- '+))) (defun back-symbol (symb) (intern (format nil "BACK-~a" symb))) ;; adding BACK-symbol computations. (defun line-to-quoted-operation-2 (line) (let* ((words (ppcre:split " " (ppcre:regex-replace ":" line ""))) (symbols (mapcar #'parse-integer-or-symbol words))) (cond ((= 4 (length symbols)) ;; with operation (destructuring-bind (name operand1 op operand2) symbols (if (eq name 'ROOT) `(progn (defparameter ,(back-symbol operand1) '(eval ,operand2)) (defparameter ,(back-symbol operand2) '(eval ,operand1))) (let ((forward-calc `(defparameter ,name '(,op (eval ,operand1) (eval ,operand2)))) (backward-calc (case op ('+ `((defparameter ,(back-symbol operand1) '(- (eval ,(back-symbol name)) (eval ,operand2))) (defparameter ,(back-symbol operand2) '(- (eval ,(back-symbol name)) (eval ,operand1))))) ('- `((defparameter ,(back-symbol operand1) '(+ (eval ,(back-symbol name)) (eval ,operand2))) (defparameter ,(back-symbol operand2) '(- (eval ,operand1) (eval ,(back-symbol name)))))) (t `((defparameter ,(back-symbol operand1) '(,(reverse-operation op) (eval ,(back-symbol name)) (eval ,operand2))) (defparameter ,(back-symbol operand2) '(,(reverse-operation op) (eval ,(back-symbol name)) (eval ,operand1))))) ))) `(progn ,forward-calc ,@backward-calc ;; (defparameter ,(innern (format t "BACK~a" name) )) ))))) ((= 2 (length symbols)) ;; just number (destructuring-bind (name value) symbols `(defparameter ,name ,value)))))) (defun load-file-defs-2 (filename) (loop for line in (uiop:read-file-lines filename) for definitions = (line-to-quoted-operation-2 line) do (eval definitions)))