Advent-of-Code/day21.lisp

99 lines
3.5 KiB
Common Lisp

;; // 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)))