Skip to content
Permalink
Browse files

Add some documentation to my solution for 2017 day21

  • Loading branch information...
iamFIREcracker committed Mar 10, 2019
1 parent aec2a9c commit 0e47962ac47d568573d16a08d8d8be27b9f21a12
Showing with 92 additions and 5 deletions.
  1. +92 −5 2017/day21.lisp
@@ -38,6 +38,22 @@
:finally (return (apply #'mkstr pixels))))

(defun generate-patterns (original &aux (size (size original)))
"Generate all the transformations of `original` by rotating it, flipping
it, or rotate and flipping it.
It turns out all the possible transformations can be generated by first
rotating (either clockwise, or counter-clockwise) and then flipping the result
(again, either vertically, or horizontally); so:
- original
- original | flip
- original | cw
- original | cw | flip
- original | cw | cw
- original | cw | cw | flip
- original | cw | cw | cw
- original | cw | cw | cw | flip
"
(let* ((rotated-cw1 (select-pixels original (indices-rotate-cw size)))
(rotated-cw2 (select-pixels rotated-cw1 (indices-rotate-cw size)))
(rotated-cw3 (select-pixels rotated-cw2 (indices-rotate-cw size))))
@@ -70,13 +86,84 @@
(gather (select-pixels pixels (indices-square i j sub-size))))))))

(defun combine (squares &aux (size (size squares)))
;; XXX review this?!
"Combines `squares` together into a bigger pixel grid.
Given the following list of squares (outputs of the rules book):
(((##.)
(#..)
(...))
((##.)
(#..)
(...))
((##.)
(#.#)
(.##))
((##.)
(#.#)
(.##)))
COMBINE will generate the following grid, serialized into a string -- without
pipes and dashes:
##.|##.
#..|#..
...|...
---+----
##.|##.
#.#|#.#
.##|.##
How? `size` input squares are required to generate a row of tiles, and since
each square is a list of lists containing the configuration of pixel for each
square row, we can use MAPCAR with MKSTR incrementally build 1 x `size` new
tile; finally, all the 1 x `size` tiles will be joined together into the final
string representing the new pixel grid
Example:
(((##.)
(#..)
(...))
((##.)
(#..)
(...))
((##.)
(#.#)
(.##))
((##.)
(#.#)
(.##)))
For the first 1 x `size` tile, we will use the first two squares
(((##.)
(#..)
(...))
((##.)
(#..)
(...))
Passing these to MAPCAR and MKSTR we would get:
##.##.#..#........
The second set of squares would instead generate the following string:
##.##.#.##.#.##.##
You combine them together with MKSTR and you get
##.##.#..#........##.##.#.##.#.##.##
_painting_
"
(loop
:for start = 0 :then end
:for end = (+ start size)
:while (< start (length squares))
:for foo = (subseq squares start end)
:collect (apply #'mkstr (apply #'mapcar #'mkstr foo)) :into lines
:for line-squares = (subseq squares start end)
:collect (apply #'mkstr (apply #'mapcar #'mkstr line-squares)) :into lines
:finally (return (apply #'mkstr lines))))

(define-problem (2017 21) (data parse-rules)
@@ -86,8 +173,8 @@
:with pixels = ".#...####"
:with part1
:for iteration :from 1 :upto 18
:for grids = (break-up pixels)
:for expansions = (mapcar (curry #'gethash _ data) grids)
:for sub-grids = (break-up pixels)
:for expansions = (mapcar (curry #'gethash _ data) sub-grids)
:do (setf pixels (combine expansions))
:when (= iteration 5) :do (setf part1 (pixels-on pixels))
:finally (return (values part1 (pixels-on pixels))))))

0 comments on commit 0e47962

Please sign in to comment.
You can’t perform that action at this time.