adventofcode2022

My solutions for Advent of Code 2022
Log | Files | Refs

commit 6e001c3958573cf0405b0dcce36562249128a024
parent a2d0a6eff5d84df8ef90e97f21847edf03dd8fcf
Author: Lukas Henkel <lh@entf.net>
Date:   Fri,  9 Dec 2022 13:35:09 +0100

Day 9 task 2

Diffstat:
Msrc/day09.lisp | 44+++++++++++++++++++++++++++-----------------
Mt/day09.lisp | 18++++++++++++++++--
2 files changed, 43 insertions(+), 19 deletions(-)

diff --git a/src/day09.lisp b/src/day09.lisp @@ -1,5 +1,6 @@ (defpackage #:adventofcode2022/day09 - (:use #:cl #:adventofcode2022)) + (:use #:cl #:adventofcode2022) + (:import-from #:alexandria #:clamp)) (in-package #:adventofcode2022/day09) (defun move-head (head dir) @@ -14,20 +15,11 @@ (<= (abs (- (car head) (car tail))) 1) (<= (abs (- (cadr head) (cadr tail))) 1))) -(defun move-tail (tail dir head) - (cond - ((char= dir #\U) - (setf (car tail) (car head)) - (setf (cadr tail) (1+ (cadr head)))) - ((char= dir #\D) - (setf (car tail) (car head)) - (setf (cadr tail) (1- (cadr head)))) - ((char= dir #\L) - (setf (car tail) (1+ (car head))) - (setf (cadr tail) (cadr head))) - ((char= dir #\R) - (setf (car tail) (1- (car head))) - (setf (cadr tail) (cadr head))))) +(defun move-tail (tail head) + (incf (car tail) + (clamp (- (car head) (car tail)) -1 1)) + (incf (cadr tail) + (clamp (- (cadr head) (cadr tail)) -1 1))) (defun task1 (inputs) (loop with visited-positions = (make-hash-table :test 'equal) @@ -38,13 +30,31 @@ do (loop for i from 1 to steps do (move-head pos-head dir) unless (head-tail-touching-p pos-head pos-tail) - do (move-tail pos-tail dir pos-head) + do (move-tail pos-tail pos-head) and do (setf (gethash (copy-seq pos-tail) visited-positions) t)) finally (return (hash-table-count visited-positions)))) +(defun task2 (inputs) + (loop with visited-positions = (make-hash-table :test 'equal) + with positions = (loop repeat 10 collect (list 0 0)) + with pos-head = (car positions) + with pos-tail = (car (last positions)) + initially (setf (gethash (list 0 0) visited-positions) t) + for (dir steps) in inputs + do (loop for i from 1 to steps + do (move-head pos-head dir) + do (loop with previous = pos-head + for knot in (cdr positions) + for i from 1 + unless (head-tail-touching-p previous knot) + do (move-tail knot previous) + do (setf previous knot)) + do (setf (gethash (copy-seq pos-tail) visited-positions) t)) + finally (return (hash-table-count visited-positions)))) + (define-day 9 (:translate-input (lambda (line) (list (aref line 0) (parse-integer (subseq line 2))))) #'task1 - nil) + #'task2) diff --git a/t/day09.lisp b/t/day09.lisp @@ -1,6 +1,6 @@ (in-package #:adventofcode2022/test) -(defconstant +testdata-day09+ "R 4 +(defconstant +testdata-day09-task1+ "R 4 U 4 L 3 D 1 @@ -9,9 +9,23 @@ D 1 L 5 R 2") +(defconstant +testdata-day09-task2+ "R 5 +U 8 +L 8 +D 3 +R 17 +D 10 +L 25 +U 20") + (def-test day09-task1 () (is-true (= 13 (run-task 9 1 - (make-string-input-stream +testdata-day09+))))) + (make-string-input-stream +testdata-day09-task1+))))) +(def-test day09-task2 () + (is-true + (= 36 + (run-task 9 2 + (make-string-input-stream +testdata-day09-task2+)))))