99 lines
3.5 KiB
Common 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)))
|