aboutsummaryrefslogblamecommitdiffstats
path: root/day18.lisp
blob: 0b35af2d8c37a22ef7115e69a52c7ce8767e59a5 (plain) (tree)






























































                                                                          
(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