(defun read-lines (filespec) (with-open-file (stream filespec) (loop for line = (read-line stream nil) while line collect line))) (defun split-by-char (char string) (loop for i = 0 then (1+ j) as j = (position char string :start i) collect (subseq string i j) while j)) (defun compute-area (moves) (let* ((coords '((0 . 0))) (interior 0) (bound 0 )) (loop for m in moves as dir = (car m) as len = (cdr m) as prv = (car coords) as prvi = (car prv) as prvj = (cdr prv) as curi = (cond ((equal dir #\U) (- prvi len)) ((equal dir #\D) (+ prvi len)) (t prvi)) as curj = (cond ((equal dir #\L) (- prvj len)) ((equal dir #\R) (+ prvj len)) (t prvj)) as cur = (cons curi curj) do (setf coords (cons cur coords) interior (+ interior (- (* prvi curj) (* prvj curi))) bound (+ bound (abs (+ (- curi prvi) (- curj prvj)))))) (1+ (ash (+ (abs interior) bound) -1)))) (defun get-move (line) (let ((aux (split-by-char #\Space line))) (cons (aref (car aux) 0) (parse-integer (cadr aux))))) (defun get-moves (lines) (mapcar #'get-move lines)) (defun solve1 (filespec) (let* ((lines (read-lines filespec)) (moves (get-moves lines))) (compute-area moves))) (defun get-swapped-move (line) (let* ((aux (caddr (split-by-char #\Space line))) (aux (parse-integer aux :start 2 :radix 16 :junk-allowed t))) (cons (aref "RDLU" (mod aux 16)) (ash aux -4)))) (defun get-swapped-moves (lines) (mapcar #'get-swapped-move lines)) (defun solve2 (filespec) (let* ((lines (read-lines filespec)) (moves (get-swapped-moves lines))) (compute-area moves))) (print (solve1 "data/18/example.txt")) ;; 62 (print (solve1 "data/18/input.txt")) ;; 34329 (print (solve2 "data/18/example.txt")) ;; 952408144115 (print (solve2 "data/18/input.txt")) ;; 42617947302920