(defpackage #:advent.2024.09 (:use #:cl #:advent.2024.00) (:import-from #:serapeum #:take-while) (:import-from #:alexandria #:compose)) (in-package #:advent.2024.09) (defparameter *input* "09.example") ;;; Day 1. ;; 1. Decode / expand compact disc map representation ;; 2. Move blocks left to fill empty space ;; 3. Checksum (defun decode (&optional (str (uiop:read-file-line *input*))) (loop with id = 0 with res = (make-array '(1000) :adjustable t :fill-pointer 0) for c across str for n = (parse-integer (string c)) while n for filep = t then (not filep) if filep do (progn (loop for i from 1 to n do (vector-push-extend id res)) (incf id)) else do (loop for i from 1 to n do (vector-push-extend nil res)) finally (return res))) (defun shift (&optional (str (uiop:read-file-line *input*))) (let* ((mem (decode str)) (rev (nreverse (remove-if #'null (vector->list mem))))) (loop for i from 0 below (length rev) collect (or (aref mem i) (pop rev))))) (defun checksum (&optional (str (uiop:read-file-line *input*))) ; also solve1 (loop for i from 0 for n in (shift str) sum (* i n))) ;;; 24551621791131 is too high ;; ... change `until (eq beg end)` to `until (> beg end)` ... ;; 2096 is too low ;;; ... change to (>= beg end) ... ;; 6415449222092 is too high ;; 6414919955263 is wrong ;; 6415184586041 IS RIGHT THANK GOD :) ;;; Part 2. ;; Move whole files instead of just blocks..... ;; ex. ;; 00...111...2...333.44.5555.6666.777.888899 ;; 0099.111...2...333.44.5555.6666.777.8888.. ;; 0099.1117772...333.44.5555.6666.....8888.. ;; 0099.111777244.333....5555.6666.....8888.. ;; 00992111777.44.333....5555.6666.....8888.. ;; Do i want to redefine the input format to be a list of files with size and ;; id? (defun length-encode (v) (do ((i 0 (1+ i)) tmp res (start 0)) ((>= i (length v)) (nreverse (cons (list (car tmp) start (length tmp)) res))) (if (eq (aref v i) (car tmp)) (push (aref v i) tmp) (progn (push (list (car tmp) start (length tmp)) res) (setf tmp (list (aref v i))) (setf start i))))) (defun shift2 (&optional (str (uiop:read-file-line *input*))) (let* ((mem (length-encode (decode str))) (frees (remove-if-not (compose #'null #'car) mem)) (files (nreverse (remove-if (compose #'null #'car) mem)))) (loop for (id . len) in files if (find len frees :key #'third) )))