yay, day 22. part 1

This commit is contained in:
efim 2022-12-31 14:41:30 +00:00
parent 5630acd513
commit f2c18830c2
6 changed files with 561 additions and 0 deletions

200
day22-map.txt Normal file
View File

@ -0,0 +1,200 @@
......#....#.#........................................#.......##...........#.............#......#...
..............#..#........#......##........................#......#....#........................#...
.....................#.........#...#.#........#..............................#....#........#..#.....
.........#.........##................................#.....#.........#...........#...........#......
..........#.............#.....##.......#..#..........##......#.#...........#............##..........
......#.............##.........#.....#....#...............................................#.......#.
..#......#......#.........#..#.........#....#...................#...........#...#.....##.#..#...#..#
#.#.............#.............#.#......#.....#.....#.##.##.....#...#..#...............#.............
.#....#...##....#...................#..#............................................#.........#.....
....#..##....#..#....#..............#..#...#...#................#...........#..#..#............##...
..#.#....................................................................#.....##....##.....#..#....
.......#...#......#...##........#...#......................#.#.#..............#...#..#.....#........
.....#.#..#........#..............##......#........##...............#..................#.....#......
.......#...............#...#...................................#............#.......................
......#..##.....#.......#....#..................................................#.#.......#.........
................#..#..#....#.#.....................#................................................
.................#.#........#.....##...#...#.#..#....#....#.............#...#..................#..#.
.#...................#......#..#...............#.............#.........................#...#.....#..
...#.#...................#...#.........................#.......##.......................#.........#.
.#.............................#........##.........#.#.....##.....................#....#...........#
..........#.....#..............................#................##.....................#.......#....
.....................................#....##..........#...............#.......##.........#.#........
....#.###............#....#..........#..........#.......................#...............#....#.#....
.#...#...#...............#.........#........................#.................#..................#.#
.................#......#.....................#........#......#.....................#....#.##.......
##..#....................#.....................#....#....#.....#.............................#.....#
#...#.......................................................##.#...#.........#..#...................
............#......#.....#........#..#.#......#.#.............#....#......#.#...............#.......
..................................................#.#..........##.........##......#.#.#.........##..
..#..........................#.......#..#..#.......#.................###.......#...........#..#...##
..#.....#..#...#.....#.....#...#..#.................................#.....#.........#.............#.
............#.#..#..##..#.#.##....#...............#.......#........#............#........#..........
.#...........#...........................#............#.....#.#.........#.....#.......###...#.......
...#.......................#.........................#...##........#.....................#.......#..
...........#..#.............................#.................#..##...#.............................
..................#.#...#..#....#....#..........#................#..#.........#......#.......#......
...#...#....#.#................#.............#.............................#..#.....................
....................#.........#..#.#...#.#.##...#...#..............#.......#.........#.............#
...#.....#.............##.....#....#.#.......#......................................................
..........#..#...#.......................#.................##.....#........#...#......#.......#.....
........#......#...............#.#.....#...........................#.....................#.......#..
..................................#...........#......#...........#.............#....###.............
................#.......................#.#......#.##..........#......#............#................
.........................................#..........................................##...........#..
...#.......#....##.#....#...............#..#...#.............#...#....#.....#.#...........#.........
#........#...........#...........#.....................#........#..................#.....#......#...
........#.....##..#.........................#....#..........#.##..#.......#.#.................#...#.
..........................#.............................#........#............#.............#....#..
.............................#..................................................#...................
................#.............#..#..........##......#......#.........#...........##............##...
#...#.......#.............#............#..........
#................#...#....#..................#....
.................#.....#.#....#......#...#........
..................................#...............
.....#...............................#............
...............#............##..........#.......#.
#............#.....................###.#.........#
.#...............#...........#....#......#........
.#.............###.#................#........#....
....##............#..........#.#.........#.#.#....
..................#..#..............#......#......
....#.............................#...............
.#.#..........#...........#......##...............
..........#......#....#...#.#....#..#.............
................#...............#.................
..........#..#...#..............#...............#.
...#..............##..............#...............
..#...#.#....#.........#.........#.......#........
.................#..............#.........#.....#.
.......#........#......#............#......#......
..........#..............#....#..#............#...
.......#............#.............#...............
.....#.#..........#.#..........#..................
#...#...................#......#......#.....#.....
........#........##.#.......##................#...
..................#.........................##....
..#................#..............#.#....#.#.#...#
........#..........................#..........#...
..#.......#.#............#..........#.....#.......
....#....#...............................#........
..#............................................#..
....#.......#..............##.......#......##.....
.#..........#......#....#.#........#..............
................#.#.......##.............###.....#
...............#......##.#...#................#...
....#.......#....##...#..#..........#.........#...
.....#.........#...#...........#........#.........
.......#...............#..................#.......
...........#.....#.........#........#....#.......#
..#.....................................#...#.....
..................#..............#....#.#.........
........................#.......#.#......#........
...#......#..#..........#..#..#........#..........
.....#.......#.........#.............#.......#....
......#......#...............#.....#.........#....
.#.........................#.....#.............#..
...#......#.#.....##...#.#....#.#...............#.
.............#........#.#.#.....#.................
...#.........#.........#....#.................##..
.......#.......##...#....#..........#.#...........
..#......#....................#.........#........#.....................#............#.....#.........
.##...........##...................#.#..................................#...........................
....#............#..........#..........................#...#......................#....##...........
.#...........#........................#..............................#..#...................#......#
#................#.#........#...........................#....................#...........#..........
#.....................#.....#.......##....#......#..##...#...........#...................#..........
.........#..#......#....#......#....#.......#.....................................................##
..#...#......##.#..................#.......#.............#....#....#.........#..............#.....#.
...........#...#...#.#........#..................##...........#.....#...............................
.............................#....##..#..#..........#.............................#.................
...#.................#...#...#...#.................................................#..............##
......#........#........#.........##....#....#.....#.......#.............#...##.##.#................
..#.......................#....................#..#...#.................#......#..........#......#..
.........................#....#..##..............#.............#.#...#....#.......#...#....#.....#..
....#................#.#...........................#....#..#.......##.#.....#................#.#....
..#.......................#.....#...#..#..#...#...#.............................#............#......
#..............................................#.......................................##........#.#
..............#.#............##..........#.........................#..................#.#...........
.....#......................#...........#.....#.................#................#........#...#..#.#
......#.#....#......#.#..................#.#................#.#.#...........#............#.....#....
.#......#......##..............#.........#.#.#.#..................#...#..........#..................
...#...........#.............#....#.#...#....#.......................#.#.....#.....#..............#.
...#...#.#.........#...#............#....#.........#.....#......#..#...........#.....#......#.......
.#.....#..........#..............#..#........#..............#...#.............#.#.......#..#........
.....#........................#.....#......#...............##..#.#...#...#.#............#...........
.....#......#.........#....#.......##.......#.##..................#...............#......#........#.
.#..#..#..#.................................#......#.#............#..#....#...................#.....
.#..#...........................#....#............................................................#.
......#..............................#..#.......#.........##..........##...#........................
............#...............#..#..#..........#......................#...#.#............#............
...##..................#.....#.........#......#...........#.......#.....#.......................#...
..#..#..#......#......#.....#.......#.................##..#.........................................
............#...##...#..........#.................................##....#........##........#........
...##...#....#....#........................#.............##.........................##.......#......
.............##..................#...................##.......#........##.............#.#..........#
.......#.....#...##..............#..........................#..........#..........#..#.............#
............#...#........#........#...............#.....#.....#.......#..............#.....#......#.
...........#.....#..##.................#......#........#.#.....................#....................
.....#......#.........#..........#..#......................................................##.......
..........#.....#......#.#.........#.....#..................##.............................#........
##......#...#..........#...............#.............#........#..................#........#........#
..#.........#...........#.......#...........##...................#.................#.#.....#...#....
...#.........#..................................#.....#..#............#.............#.#.............
....#...........#..........#..............#..###........#..#.........#....................#.#.......
..#..........#..#...............................#...#.................#............#............#.#.
.....................#.............#....#..#....#......................#..#......#..................
........#.#.............#....#...#.#.....#..........#................#.......#........#....#.#.....#
##.........................##....#...............#..........#......................##...............
.........#..................................#........................#....#............#...#.#......
........#........................#..#...#..........................#................................
................#..#.......#..#...................
.............#........#...................#.......
..#....#.......................#..........#...#..#
..........#.....................#..............#.#
.........#...#...#..............#..#.........#....
...........#.....#................................
.......#..#..#.......#............#...............
.........................#..........#..#....#..#..
#...........#....#.....#....#.#..#.......#........
#.#.......#.....#........#....#...#...............
..............................................#...
#......#....................................#...#.
........##..#.....#.#......#.........#..##....#...
...............#.........#...#.......#......#..#..
..........#.#......#.....#........................
.....#.....#......................................
..#..#............#.......#.....#..#.......#...#..
...............##....#........#..#.............#.#
..............#..................#.....#......#...
#.......#.......#...#...............#.#....#......
#.........#........#..........#........#....#.....
.....###.#...........#...........##............#..
.........#..##.......#......................#.....
.....#.##......#.......#...#.............#........
##.................#.....#.............#....#...#.
........#..............#.#.........#.......#......
........#..#.#.....#.............#............#..#
.#.....#.#..#..#.##........#..........#.....##....
.....#....#.........#.............................
................#..#....#.....#....#........#..#..
#.#............#.....#.............#.........#....
...#....#..........#.#.................#.#..#...#.
........#................#...#......#......#...#.#
..#.............#....#.......#..............#.....
.....................................##.........#.
............#.#...................................
..#...........................#..........#........
...#.............#..............#..........#...#..
#......#...#...#...#...#..................#....#..
....#......#..#....#.#.#..........................
..#.......................#..............#..#.....
................#........#...#..........#.#.......
....#...#......#...................#.#.#...#....#.
............#..............#........#..#.....#....
..........#...............#.......#...............
#....................#.......#...........#........
.......#.........#..........#.#..#.#..............
..#.........##......................#...#.........
...#.................#.##............#........#...
....#......#..#.....................#.............

1
day22-path.txt Normal file

File diff suppressed because one or more lines are too long

206
day22-scratch.lisp Normal file
View File

@ -0,0 +1,206 @@
;; https://adventofcode.com/2022/day/22
(in-package :day-22)
;; monkey map. so, i'd want to store the map.
;; and have functions that return "neighbors" maybe as alist?
;; neighbor is the right place to calculate wrapping around empty space
;; on top of neighbors get walkable directions
;; how to best represent coord?
;; next - moving
;; looking at the map of input. maybe somehow precompute where to jump on the map?
;; nah.
;; so, let's get map. with chars space, dot, hash
;; have line of spaces at the start, end, left and right?
;; that would shift coords by +1
;; and i'd also like what? i'd also like to store the path?
;; when exiting save that last orientation at the point?
;; and only treat space and hast as special, dot and arrows as walkable
;; or i could print "every snapshot" with setting and removing the walkout
;; i could split the input into files, that would simplify things
;; let's read the map into array?
(setq *ugh*
(let* ((lines (uiop:read-file-lines "day22-test-map.txt"))
(rows (length lines))
(cols (apply #'max (mapcar #'length lines)))
(arr (make-array (list (+ 2 rows) (+ 2 cols)) ; adding for padding row of empty space
:initial-element #\ )))
(loop for row from 0 below rows
for line = (coerce (nth row lines) 'array)
do (loop for col from 0 below cols
for char = (if (array-in-bounds-p line col) (aref line col) #\ )
do (setf (aref arr (1+ row) (1+ col)) char)))
arr))
(setq *test-arr-out-bounds* (make-array '(2 2) :initial-element #\. :adjustable t))
(print-map *ugh*)
;; yep, this is what i want
(print-map (read-map-to-array "day22-map.txt"))
(setq *ugh* (read-map-to-array "day22-test-map.txt"))
;; seems to work.
;; what are next steps?
;;
;; for some coords get neighboring to four sides
;; this should just return coords even with wrapping
;; let's first do function that returns coord or wrapped coord if value is space?
(alexandria:assoc-value *movements* 'left)
;; so from coord as list to updated coord
(move-coord-one-step '(1 1) 'right)
;; next should check the value of the moved. and if it's space -
;; calculate wrap
;; would also take the map array
;; if we're out of bounds, just skip this movement. shouldn't happen in my data
(opposite-movement 'left)
(opposite-movement 'right)
(opposite-movement 'down)
(opposite-movement 'up)
(apply #'aref *ugh* '(1 12))
;; now i need to check that. hm.
*ugh*
(print-map *ugh*)
'(4 1) ; begining of part
(move-with-possible-wrap '(5 1) 'left *ugh*)
(aref *ugh* 5 0)
(let ((coord '(5 1))
(map *ugh*)
(direction 'left))
(do
((mov-coord coord
(move-coord-one-step mov-coord (opposite-movement direction))))
((equal #\ (apply #'aref map mov-coord)) (move-coord-one-step mov-coord direction))))
;; now? um
(move-with-possible-wrap '(5 2) 'up *ugh*) ; now that seems ok
;; next is from 'move-with-possible-wrap
;; i guess i'd alreay want to display?
;; set X on that coord?
(display-coord '(5 2) *ugh*)
(display-coord (move-with-possible-wrap '(5 2) 'up *ugh*) *ugh*)
;; yeah, kind of ok.
;; what next? simulate movement?
(move 4 'right '(1 1) *ugh*)
(display-coord '(6 1) *ugh*)
(display-coord (move 4 'right '(6 1) *ugh*) *ugh*)
(display-coord '(6 8) *ugh*)
(display-coord (move-with-possible-wrap '(6 8) 'left *ugh*) *ugh*)
(display-coord (move 1 'left '(6 8) *ugh*) *ugh*)
(display-coord (move 2 'left '(6 8) *ugh*) *ugh*)
(display-coord (move 3 'left '(6 8) *ugh*) *ugh*)
(display-coord '(6 8) *ugh*)
(display-coord (move-with-possible-wrap '(6 8) 'right *ugh*) *ugh*)
(display-coord (move 1 'right '(6 8) *ugh*) *ugh*)
(display-coord (move 2 'right '(6 8) *ugh*) *ugh*)
(display-coord (move 3 'right '(6 8) *ugh*) *ugh*)
(display-coord '(6 2) *ugh*)
(display-coord (move-with-possible-wrap '(6 2) 'left *ugh*) *ugh*)
(display-coord (move 1 'left '(6 2) *ugh*) *ugh*)
(display-coord (move 2 'left '(6 2) *ugh*) *ugh*)
(display-coord (move 3 'left '(6 2) *ugh*) *ugh*)
(display-coord (move 4 'left '(6 2) *ugh*) *ugh*)
(display-coord (move 5 'left '(6 2) *ugh*) *ugh*)
(display-coord (move 6 'left '(6 2) *ugh*) *ugh*)
;; ok, i guess
;;
;; and now code the walk?
(defparameter *test-path* "10R5L5R10L4R5L5")
(ppcre:split "(L|R|U|D])" *test-path* :with-registers-p t )
;; somewhat of what i want, but also lrud into words
(mapcar #'parse-integer-or-symbol
(ppcre:split "(L|R)" *test-path* :with-registers-p t ))
;; initial number is "forward" from initial direction
;; oh, so the path is with turns Right turn or Left turn.
;; with initial Right
;; so, now i'd want a fuction that transformes direction
;; i guess i could what? make cyclic list? not quite i guess
(alexandria:circular-list 'up 'right 'down 'left)
(position 'up (alexandria:circular-list 'up 'right 'down 'left))
(nth (mod -1 4) (alexandria:circular-list 'up 'right 'down 'left))
;; yeah i guess
(new-direction 'UP 'L)
(new-direction 'LEFT 'L)
(new-direction 'down 'L)
(new-direction 'right 'L)
(new-direction 'UP 'R)
(new-direction 'LEFT 'R)
(new-direction 'down 'R)
(new-direction 'right 'R)
;; yay. that's kind of ok
;; now. ugh
;; yup, let's add that in code...
(append (read-path "day22-test-path.txt") (list 'L))
(read-path "day22-path.txt")
;; the path is "go N to your direction"
;; then L or R to change direction
;; so, now the main loop?
;; i guess i could add one more R or L to the end
;; and treat path as (n turn-direction)
;; oh, but the final direction is part of the answer
;; OK, LET'S add L to the end
(let ((padded-path (append (read-path "day22-test-path.txt") (list 'L)))
(direction 'right)
(coords '(1 1)) ; to be calculated
(map *ugh*)
)
(loop
for (n turn-direction) on padded-path by #'cddr
do (progn
(setq coords (move n direction coords map))
(setq direction (new-direction direction turn-direction)))
finally (return (list coords direction))))
;; hoho. the task requires indices starting from 1, cool
;; and i did 1 too many left turns, so let's turn right
;; UP to right, is RIGHT
;; and 0 for right, cool
;; yay! now let's clean it up.
;; one more thing. determining top leftmost point.
(get-topmost-left-coords *ugh*)
(print-map *ugh*)
(apply #'calc-password (walk-path "day22-test-path.txt" "day22-test-map.txt"))
(apply #'calc-password (walk-path "day22-path.txt" "day22-map.txt"))
;; 11464
;; and one gold star.

12
day22-test-map.txt Normal file
View File

@ -0,0 +1,12 @@
...#
.#..
#...
....
...#.......#
........#...
..#....#....
..........#.
...#....
.....#..
.#......
......#.

1
day22-test-path.txt Normal file
View File

@ -0,0 +1 @@
10R5L5R10L4R5L5

141
day22.lisp Normal file
View File

@ -0,0 +1,141 @@
;; https://adventofcode.com/2022/day/22
(defpackage :day-22
(:use :cl))
(in-package :day-22)
(ql:quickload 'alexandria)
(ql:quickload 'fiveam)
(ql:quickload 'cl-ppcre)
(5am:def-suite :day-22-test)
(defun read-map-to-array (filename)
(let* ((lines (uiop:read-file-lines filename))
(rows (length lines))
(cols (apply #'max (mapcar #'length lines)))
(arr (make-array (list (+ 2 rows) (+ 2 cols)) ; adding for padding row of empty space
:initial-element #\ )))
(loop for row from 0 below rows
for line = (coerce (nth row lines) 'array)
do (loop for col from 0 below cols
for char = (if (array-in-bounds-p line col) (aref line col) #\ )
do (setf (aref arr (1+ row) (1+ col)) char)))
arr))
(defun print-map (arr)
(loop for row from 0 below (array-dimension arr 0)
do (let ((line (make-array (array-dimension arr 1)
:displaced-to arr
:displaced-index-offset (* row (array-dimension arr 1)))))
;; (format t "~a~%" (coerce line 'string))
)))
(defconstant *movements*
'((left . (0 -1))
(right . (0 1))
(down . (1 0))
(up . (-1 0))))
(defun opposite-movement (movement)
(let ((alist '((left . right) (down . up))))
(or (alexandria:assoc-value alist movement)
(alexandria:rassoc-value alist movement))))
(defun move-coord-one-step (coord direction)
(mapcar #'+ coord (alexandria:assoc-value *movements* direction)))
(5am:def-test move-coord-left (:suite :day-22-test)
(5am:is (equalp (move-coord-one-step '(2 2) 'left)
'(2 1))))
(5am:def-test move-coord-right (:suite :day-22-test)
(5am:is (equalp (move-coord-one-step '(2 2) 'right)
'(2 3))))
(5am:def-test move-coord-up (:suite :day-22-test)
(5am:is (equalp (move-coord-one-step '(2 2) 'up)
'(1 2))))
(5am:def-test move-coord-down (:suite :day-22-test)
(5am:is (equalp (move-coord-one-step '(2 2) 'down)
'(3 2))))
(defun move-with-possible-wrap (coord direction map)
(let ((initial (move-coord-one-step coord direction)))
(if (not (equal #\ (apply #'aref map initial)))
;; when not wrapping
initial
;; when map on initial movement is empty - wrap
(do
((mov-coord coord
(move-coord-one-step mov-coord (opposite-movement direction))))
((equal #\ (apply #'aref map mov-coord)) (move-coord-one-step mov-coord direction))))))
(defun display-coord (coord map)
(let ((copied (alexandria:copy-array map)))
(setf (apply #'aref copied coord) #\X)
(print-map copied)))
(defun move (n direction coord map)
(do* ((prev-coord coord next-coord)
(next-coord (move-with-possible-wrap coord direction map) (move-with-possible-wrap next-coord direction map))
(count 0 (1+ count)))
((or (= count n)
(equal #\# (apply #'aref map next-coord)))
prev-coord)
;; (format t "before move, iter ~a~%" n)
;; (display-coord prev-coord map)
;; (format t "after move, iter ~a~%" n)
;; (display-coord next-coord map)
))
(defun new-direction (direction turn-to)
(let* ((directions-cycle '(UP RIGHT DOWN LEFT))
(turn-mod '((L . -1) (R . 1)))
(cur-dir-pos (position direction directions-cycle))
(new-pos (mod
(+ cur-dir-pos (alexandria:assoc-value turn-mod turn-to))
4)))
(nth new-pos directions-cycle)))
(defun parse-integer-or-symbol (str)
(let ((maybe-int (parse-integer str :junk-allowed t)))
(if maybe-int
maybe-int
(intern (string-upcase str)))))
(defun read-path (filename)
(mapcar #'parse-integer-or-symbol
(ppcre:split "(L|R)" (uiop:read-file-string filename) :with-registers-p t )))
(defun get-topmost-left-coords (map)
(loop for col from 0 below (array-dimension map 1)
do (when (equal #\. (aref map 1 col))
(return (list 1 col)))))
(defun walk-path (path-filename map-filename)
(let* ((padded-path (append (read-path path-filename)
(list 'L)))
(direction 'right)
; to be calculated
(map (read-map-to-array map-filename))
(coords (get-topmost-left-coords map))
(walk-result
(loop
for (n turn-direction)
on padded-path by #'cddr
do (progn
(setq coords (move n direction coords map))
(setq direction (new-direction direction turn-direction)))
finally (return (list coords direction)))))
(destructuring-bind ((row col) over-direction)
walk-result
(list row col (new-direction over-direction 'R)))))
(defun calc-password (row col direction)
(let* ((direction-scores '((right . 0) (down . 1) (left . 2) (up . 3)))
(direction-score (alexandria:assoc-value direction-scores direction)))
(+ (* 1000 row) (* 4 col) direction-score)))
(5am:run! ':day-22-test)