(defpackage :aoc/2024/15/tests (:use :cl :aoc :aoc/tests :aoc/2024/tests :parachute :aoc/2024/15 )) (in-package :aoc/2024/15/tests) (defparameter test-text (aoc:split-lines "######## #..O.O.# ##@.O..# #...O..# #.#.O..# #...O..# #......# ######## <^^>>>vv>v<<")) (defparameter test-data (parse-input test-text)) (define-test suite-2024-15 ;:parent suite-2024 ) (define-test test-find-robot :parent suite-2024-15 (is equalp (make-pos :x 2 :y 2) (find-robot (first test-data))) (is equalp (make-pos :x 4 :y 4) (find-robot (first sample-data)))) (defparameter map1 "######## #..O.O.# ##@.O..# #...O..# #.#.O..# #...O..# #......# ######## ") (defparameter final-sample-map "########## #.O.O.OOO# #........# #OO......# #OO@.....# #O#.....O# #O.....OO# #O.....OO# #OO....OO# ########## ") (define-test test-move-robot :parent suite-2024-15 (is equal map1 (let ((map (car test-data))) (move-robot map (subseq (cdr test-data) 0 1)) (show-map map nil))) (is equal final-sample-map (let* ((initial (car sample-data)) (actual (move-robot initial (cdr sample-data)))) (show-map actual nil))) ) ;;; -------------- Part 2 --------------------- (defparameter s2-text (aoc:split-lines "Initial state: ############## ##......##..## ##..........## ##....[][]@.## ##....[]....## ##..........## ############## Move <: ############## ##......##..## ##..........## ##...[][]@..## ##....[]....## ##..........## ############## Move v: ############## ##......##..## ##..........## ##...[][]...## ##....[].@..## ##..........## ############## Move v: ############## ##......##..## ##..........## ##...[][]...## ##....[]....## ##.......@..## ############## Move <: ############## ##......##..## ##..........## ##...[][]...## ##....[]....## ##......@...## ############## Move <: ############## ##......##..## ##..........## ##...[][]...## ##....[]....## ##.....@....## ############## Move ^: ############## ##......##..## ##...[][]...## ##....[]....## ##.....@....## ##..........## ############## Move ^: ############## ##......##..## ##...[][]...## ##....[]....## ##.....@....## ##..........## ############## Move <: ############## ##......##..## ##...[][]...## ##....[]....## ##....@.....## ##..........## ############## Move <: ############## ##......##..## ##...[][]...## ##....[]....## ##...@......## ##..........## ############## Move ^: ############## ##......##..## ##...[][]...## ##...@[]....## ##..........## ##..........## ############## Move ^: ############## ##...[].##..## ##...@.[]...## ##....[]....## ##..........## ##..........## ##############")) (defun parse-s2 (lines &optional (rslt)) (if (null lines) (reverse rslt) (let* ((move (ppcre:register-groups-bind (s) ("Move (.):" (car lines) ) (and s (char s 0)))) (split (or (position-if #'alexandria:emptyp lines) (length lines))) (rows (mapcar #'parse-line (subseq lines 1 split))) (dims (list (1- split) (length (first rows))))) (parse-s2 (subseq lines (min (1+ split) (length lines)) (length lines)) (push (cons move (make-array dims :initial-contents rows)) rslt))))) (defparameter s2-data (parse-s2 s2-text)) (defparameter test-sample2-final (let* ((rows (mapcar #'parse-line (aoc:split-lines "#################### ##[].......[].[][]## ##[]...........[].## ##[]........[][][]## ##[]......[]....[]## ##..##......[]....## ##..[]............## ##..@......[].[][]## ##......[][]..[]..## ####################"))) (dims (list (length rows) (length (first rows))))) (make-array dims :initial-contents rows))) (defparameter tc-data-test (aoc:split-lines "Initial state: #################### ##....[]....[]..[]## ##............[]..## ##..[][]....[]..[]## ##...[].......[]..## ##[]##....[]......## ##[]......[]..[]..## ##..[][]..@[].[][]## ##........[]......## #################### Move ^: #################### ##....[]....[]..[]## ##............[]..## ##..[][]....[]..[]## ##...[]...[]..[]..## ##[]##....[]......## ##[]......@...[]..## ##..[][]...[].[][]## ##........[]......## #################### ")) (define-test test-move-robot-2 (let ((last-map nil)) (loop for test-case in (parse-s2 s2-text) for move = (car test-case) for expected-map = (cdr test-case) if move do (let* ((robot (find-robot last-map))) (move-pos last-map robot move) (is equalp expected-map last-map) (setf last-map expected-map) ; reset to expected for next tests ) do (setf last-map expected-map) )) ) (define-test test-tc :parent suite-2024-15 (let ((last-map nil)) (loop for test-case in (parse-s2 tc-data-test) for move = (car test-case) for expected-map = (cdr test-case) if move do (let* ((robot (find-robot last-map))) (format t "start~%") (show-map last-map t) (move-pos last-map robot move) (format t "expected~%") (show-map expected-map t) (format t "actual~%") (show-map last-map t) (is equalp expected-map last-map) ) do (setf last-map expected-map) ))) (define-test test-sample-2 :parent suite-2024-15 (let ((actual (move-robot (big-warehouse (car sample-data)) (cdr sample-data)))) () (format t "expected:~A~%actual :~A~%" test-sample2-final actual) (is equalp test-sample2-final actual))) (define-test+run test-part1 :parent suite-2024-15 (is equal "10092" (part1 sample-data))) (define-test+run test-part2 :parent suite-2024-15 (is equal "9021" (part2 sample-data)))