diff --git a/20-trench-map/code.scm b/20-trench-map/code.scm new file mode 100644 index 0000000..6d21a53 --- /dev/null +++ b/20-trench-map/code.scm @@ -0,0 +1,76 @@ +(load "../common.scm") + +; returns a vector of the same length of input string +; where all values are 0 except for when the corresponding +; entry in the string is '#' which will have a 1 instead. +(define (string->bin-vector str) + (vector-unfold + (lambda (i) + (if (char=? (string-ref str i) #\#) 1 0)) + (string-length str))) + +; returns a binary matrix loaded from the file +; all the lines are expected to be the same lengths +(define (file->matrix file) + (let loop [(data '())] + (if (eof-object? (peek-char file)) + (matrix-from-data (reverse-list->vector data)) + (loop (cons (string->bin-vector (get-line file)) data))))) + +; palette enhancing algorihtm: +; for each pixel in input image +; gather all pixels around it to form a 3x3 matrix +; turn that matrix into a binary number, row by row +; look up new pixel value in input palette +(define (enhance image palette steps) + (let* [(new-width (+ (matrix-width image) 4)) + (new-height (+ (matrix-height image) 4)) + (new-image (filled-matrix new-width new-height 0)) + (top-left (matrix-get image 0 0 0))] + (update-matrix! + new-image + (lambda (x y v) + ; not really convinced that defaulting to the top left pixel is the right way to do it + (vector-ref palette (+ (* (matrix-get image (- x 3) (- y 3) top-left) 256) + (* (matrix-get image (- x 2) (- y 3) top-left) 128) + (* (matrix-get image (- x 1) (- y 3) top-left) 64) + (* (matrix-get image (- x 3) (- y 2) top-left) 32) + (* (matrix-get image (- x 2) (- y 2) top-left) 16) + (* (matrix-get image (- x 1) (- y 2) top-left) 8) + (* (matrix-get image (- x 3) (- y 1) top-left) 4) + (* (matrix-get image (- x 2) (- y 1) top-left) 2) + (* (matrix-get image (- x 1) (- y 1) top-left) 1))))) + (if (<= steps 1) + new-image + (enhance new-image palette (- steps 1))))) + +; for debugging purposes +; output a PGM 1bpp image file from a given binary matrix +(define (matrix->image-file matrix filename) + (when (file-exists? filename) + (delete-file filename)) + (call-with-output-file + filename + (lambda (file) + (fprintf file "P1~%~a ~a~%" (matrix-width matrix) (matrix-height matrix)) + (vector-for-each + (lambda (y line) + (vector-for-each + (lambda (x pixel) (fprintf file "~a " (- 1 pixel))) line) + (fprintf file "~%")) + (matrix-data matrix))))) + +(call-with-input-file + "input" + (lambda (file) + (let* [(enhancer (string->bin-vector (get-line file))) + (image (begin + (get-line file) ; skip empty line + (file->matrix file)))] + (let [(enhanced (enhance image enhancer 2))] + (printf "part 1:~% Lit pixels after enhancing twice: ~a~%" + (matrix-sum enhanced))) + (let [(enhanced (enhance image enhancer 50))] + (printf "part 2:~% Lit pixels after enhancing fifty times: ~a~%" + (matrix-sum enhanced)))))) + diff --git a/20-trench-map/input b/20-trench-map/input new file mode 100644 index 0000000..076365a --- /dev/null +++ b/20-trench-map/input @@ -0,0 +1,102 @@ +#######..#.##.##...##.#.#..###..##....######.#.#..#..######.#.#..#####..##.##...#..##........#.#.#...##..##.#####..####.#####..####.#.##.#.#.#.##...##.##.#....###..#...###.#.##..##....##.##.#####..#...#..#....##..##.......##.##....###...#.##...######.##.#######.#.#.#.##.#.#..##.##...##.#.##.#####.#####.###.#....###..###.##.....###..#.##.########..#.#..####..#.###...##...##....##.#.#####..#...##.#..###...##......#.....#.##....##.###..#####..##.###....#..##..##.##.#######.#.##.##.#.####..###.###..#.####..##.. + +.##..#.#....#..#.###..#..#..###..#.#.#.##.#..##.##...#.##.#.#.###.#.##...#.#####..#.#...#..#.#.###.# +.#..#####....##....#....#......###.##.#.#.#.##...##...##.##.##.###..#.####.######.#.##.#.....###..#. +###..#.##.##.##.....##..#...#..###...#####.##.#...#.#.#.....#.#..##...##..##.#..##.#.#######.....##. +.#.#.####..#.##..####.#.##.##.#.#..#####.####.#.###.####.....#.###.#.####..############...#.##...##. +###.#..#..######.#.###.....##.#...##.....#..#..##...#.#..##.....#.#..###............##.#...#..####.. +#..###....####...###.......###.##.###.#.##.##.#.#.##..#...#.##..####..###.....#.#.#######.###...#### +#####....#.#.##.#...#...#.#.#..#.#.#......####..####.##.###..####..###...#..#..##.##.#.#####.###.#.# +...#.####.##...#..####..#.#.##........#...##.......##.#.#.###.#..#..#####...#....#.##..#.#.###.##### +.#..#....##..###.#...#...#..####..#...####.#.#.#..####.#.###...#...#..#...####.#.######.##......###. +.####..##.##..###..####..##.###..#.#........##..#...##....##..#..##.#..#..##.####.##.#...###...##..# +#..###...#.#.##..#..#.....#.#........##.#.#..###..#..#.#.#.##.#######.#.##...#.#.#..##..#....#....#. +..#######.#...##...###..#....###...#.#.#...###..#..#####.###....#.#.#.#..#..#.#.#...#.#..##.##..###. +#.##.....##.....##.#..#...###.##.###..#.#.#.##..#.#.##......#.##..##..#.#.#.#.#..##.#.##..###..##.#. +...##..#..#....#.#.#..##..##.##...####..##.##..#...#.....##.....##.#.###.##.###.###......#.#...###.. +.##.#.#...#.##..##.###.#.#..#####.#.#....###.#.##.....##.###..####.#.....#..#..####.##.######.#..#.# +##.#.#...#....###..##..###.#.##.#..##..#.#..#.##.####...###....#...#.#.##...####..###...#..#..###.#. +#...####.#...##.#.##...##.##.#..##.##.#.#...#.#.##.#.###.##.#.#...###...#..#.#..###.#.#..##..#..#.#. +#.##.#.#.#..###.###.##..#...#####..###.##..#.##.##..####...###.#..##..##.#....###.#.####.###.#.##..# +.#.#.###.##....##...#....#.#.##..#.....###.#.#.#..##.##.##....#.####.##.#.#....#.####.##..#..#.##... +####.#......#.####.#...#.####...#.#.#.#..##..#.#.#.###.######.....#.#.#..##.###..##....###.#...##.#. +.#..##.#..###.#.##.#.##..###.#..##...#...##.#.#...#.##..##.##.##.....##.##..##..###.##....#.##..#... +#.#.###..####..#.#####...#.##....####..#.#.##.###....##.#######..#.#..#.##..##...#.....##.#.#.##.#.# +...#..##.....#.###.#...#.##.#......##..##.....##..###.##...####.#...###..###.#.###..#.########.##.#. +..##.#...#..####....###.####.#..#..#.....#.###.#..#..#..#.####.....##..#.#..#####.##...#.#..#.#.#... +.####...#.#...#..##...#......#.###..##...#.#.#.###.#...####.#####..#..#.########..###.##...##...#.## +##.#.#..###.####.#....######.#####.#.##.#.##..#..##....##.###.##..#.##....###..##.#.....###.####.#.. +...#.#.#.....####..######.##...#..#..##.#######..#.....###.###.......##.###...#..##..#.###.###...... +..#......#.#.......###.#######..####.#........##.#..##...###....#...###.....#.#.#..###..#.#.#......# +...#.##.#.###.#....#..#.###.###.##......######.#.###.##.##.......#..#.....##..##...#....#.######.#.. +##.#...#..#.##.#..#.#.....#####.......#.##..#..###........#.##.###..#..##.#......##..#.#.##....##.## +.##.#.#####.###...###.#..#..##..#.##..##.#..#.####..#######..############..#...#..###....####..#.#.# +#.#..#...##.#.###..#...###.##..###.#.#.#.#....#.#.##.#..#.#...#.#..###.......###.#..#..#.....####.## +..#..###...##..#.#.#...##..#...##.##.#..###.#.##.####....#...#..####.#.#.###..#....#...#.#####..##.# +#..##...###...#####.###...####.#..#...##.#..#...####.#.##..####..###.#..###.#..#.##.#.#....#...#...# +...#.#.#####.###..##.#..##.#.....#..#..###.#.####..######..#.....####.#...##.#####.###.###.#..##.#.. +.....#..#.#...###.#.#.###.###...###...##.....##.##...##..#.#..#...#...#######.......#.#.#######..#.# +######...##.#...#.#.####..#......##..#.#.##.#..#####.#..#....#..#.....##.####.####.#.##.##..#..#.... +#.#.#.#####....###.##.##...##.#.#.....###...#.#....#.####.#.#......#.#######...#.###....####.#...... +#...####.#......#.....##...#####.##..##..#.##..##.#.#..#.#..#.#.##.....#.##.#.##.###.....#.####.#.#. +..###.#..##.####..##..#...##.#....#.....#.#####..#.#.####.###.#.####.#..###....#.#.#...#.#.....#.##. +.##.#....#.....#......#.#.......####....##.###.#...#.#.#..#...##.#.##.##.#...###.#......#.....#.#### +##.#..##..###...#.##..#####...#.##......#..#..##.#.###....###..#..##...#####.#######...#.#..#...#.## +...#.#.#.#.#....#.####....#####..###...#.#..#.#....#.#.#......#.##.....####.....#####....#.#.#...### +############...###.##.##.....##..####....###.##..#####...#.###.#######.##.####.#....##.#.###..###.#. +.##.#.##.###...#.######.##..##.#.#####.######...####..###..######.###.#...####..####.#.##.###.#..... +#..#..#.#........#.##.#.........#####..#......######.###...#.#.....##.##..#####.#..##.#..##..####### +..##....#.#.####..#....#....#...##.####.#......#......####..##.....#..#..#...#..#.###.##....###..#.# +#...##.#..##...#....####...###..#..###..#.....##.#.###.#..##.#.#.#.#......#.....#..####.##.........# +##.#.##.##.#.##...#.##.#.#.#.#..#....###..#..#.......##..#.#.##...#.####...##..###.##...#...#.#...## +#.##.#.#...#....#.##..##.#...##..#.....###.##..####.##...#####....#.###.##..#..###..#..##.#....##..# +#.#.#..##.#.#....##..###.#..####....###.#..#.#.####.#.##.......#..###.#......#.##.##.###.#######..## +.#.####.#.....#.#####.#.##.####.....#.....##.#.##.......#..#.#..#..#....##....#...##.#######.#.####. +#####.###.#..##.#..####.##..##........###.######...#..###....#.#.....#..####.##..###..####.#.#....## +.##...###...###.###.#.##..#.##.##..#.#.##.##..#.###.##.........#.##.####.###...##..##.#.#...#.....#. +.#..#.#.....#.#.##..#..#######...#..####.#...#.###.###.###.#.##..#...##.#.######.#.#.##.##..#..###.. +#####.#....#.#.....#...##.#.#.#.##...#.#.###.#.....#....#......#.#.####.##.###.#..#..#.#.##...#....# +##.....#........#.#.#####.#..####...##...##.#.#.###.....###..#..#.#.#.##.###.#.###.##..#.#.###....## +#..#.#.#.#.#......#...#..##.####....#..#....#..#.#...#.#.#.##..##.#.####.#..###..##..##.####.#..#..# +#..#.####.#..###.##.#....###..#####..#####..##.########..#..###..###..#.###.#.#..#..###..#..#.#..### +.#.######.##..#..#.###..######...#.###.....#.##..#...####......#.##.#.#.##.#.#...#..##..#.#####.##.. +..#..#.#...#.....#.##.##.#####.###..#.##..#####.#.#..##.....#..####....#...##.#...#.####.#####...### +#.##...#.##.###.#..##..#.########.#.#...##.#####..##..#####.#####.######.######....#...####..#.#.#.. +.##.##..##.#...#.......#.###.####.#...##....####..#..###...#####.#...#.##.####.##.#.#.##.#..###.#..# +.#..#.#.#..#.###....###..##.....#....#....####.#.##.##.....#..#..#..#.###....##......#.#..##...#..#. +##...###.###......#.#..#.#.#######.##.#...#.##.#####....##...#..#.....###....##.#.#.###..#....#.#... +.##.##.#..#.###.###.#..#.######....#.##..##.#..#...#.#.###...#.#####...##.#.##..##..##..####..#.#..# +.##.....#....###..##.##.#.....#..######....##.###..#..#...##..#....###.####..#####...####..###.#...# +####.###...#...###...#####.#..#######.#####..#...#.##...###....#.#...#..#####.#..#..##.#.....#####.# +#.....#...######.#.#.#.#.#.###.####.#..#.....#..##.##...#.#..##..#..#.....#....######.##.#.##..#.... +#####..#..##...#....#.......#.#....##.#.#..#.#.##...##.#....####..#...#.##..#.#.#.#...#.###...###.#. +.#.#.####....#.##.###.##..###..###.##..###..##...#.##.#.####..#....#..#....#...##...##..###..##....# +.##....###.##.#...#........#...###...#..###.##.####.#.##.#.##.###..#.##..#..#...##...##...##.#..#.#. +#..##.#..#######.##.#.#.#.####.#..........#.#..##..###.##.#.#.....#....##.#####..##.###..#.#....#.## +.##.#.#.###...#...##..#####..#.###..########..#...##...###..#..###..##.....####.###..###..##.##.##.# +#..##.##.#...##..##...##..##.###....#.#...######.####.##.###.#.#..##.#.###..##.###...#.#####..###.## +..##........##..##..#.#...#.#..##.##..#..#...#.#.#..####..#...####.##...##.#....#.##.###...#.#.##... +..#.#..#.#.##.##.##.##.#....##.#######.#....##.##.......##.##..#.##..#....#.####.#.#.....#.###.###.. +#####...#.#..#.##..####...#..##.#####....#.###.##..########..###.######.#..#.#..##.#..#..#.######..# +..#...#.#....#.....#######..#.##.#.#..##.......#..##...#.##..###.#.#..##.#....###.#........#......## +#####.#..#.#.#..####...#.#......##.##.##.#...##.##...#.####...####......##..##..#.##.#####.###...... +#.#..#.#..##.###.##.##..#.#..#.###...#...###.##.#.#....#..##..##...#.###.#......#.#.###..#.####...#. +.##..#.##.#.#.##########.##.##....#.####.#.#...###.#...#.#...##.##..####.....###.##.....#.#..#.#.### +###.##.#...#.##.##.#.##.##.#.#.#.###...##..#....#.##.#..####..#..#.#.#.#......##........#..##..#..## +####...#.##.##.###.#.##.#.....###..##.#..##.##..#.##..#.##.#.##..#......#.#..##.##...#..#.#..#.#.#.. +###..#.##.##.#.##.#.#..#....#..##.##...#.......#.#..#.###.#..##.#.########..##.#..##.###...#.#.##.## +...##.#..#####..###.#.#....####.##.##....#.#.##..#..##..#...#....###.##.....#.#...####.#####....#.#. +#.####....#...#####..#..#.##..#..###..#.#....#..#.#######....#....#.#...#.####......#.##...#...##.## +##.#.#.#...#....#.....###.####.####.##.......####.####..#...#...#.#..#.#.##....#.#...#.########....# +##..#...#.##.##..#.#.##...###.##..#..#...#.#.#.#...#.#..#.#..#...#.#...#.#.##.###.....#.##.####.#... +.###..#....#.....#.#.#..#..#######...#..#.###..##.#.#####.#..###....#.#..#.##..#.#.#......#..###..## +##..#.####.##..###.##..#.##....##.##....######..#.##..###.##.#.##..####..#.###.###.#.####..#..###### +.#.##.##...#....#.#.#..##.##.#####.##.#.###.##.....#.##.####...#..##...#.####.#.#.....#...###...###. +...#...###.......###...#.#..#....#...##.#.#####.###.#..#.##.#.##.##...#...##########.#.#.#.###.#.#.. +###...#.......#.#.#.###...#...####.#.##.##..#..###.####.#....##.#.##..#.####.########.######.##...## +.#...##..#...#..##.##.#....#.##..###.#..###......###..###.....#.#.#..#.####.#...###....####...##..#. +#.##.###.#####.####.#.#.........#...#....###...#.#..#.#...###...##..#...#..#.#.#..#####..#.####.##.# +...##.###.###..###.#.####.##.#....#.....#.#.###..#.#.....#.#.##..###.#.##.#.#.##..###...#.##..##..#. +##...#.#.##..####..#.##........#..#.####.####.#..#..###.#.#####..#....#...##.#.###......#.#####.#.#. +#...##..#.###..#.#.#...###..#.#.#....#....#..##.###.#.#....#....#.#.#.##...#.#..##....#.####..##.### +#.###.#....#.###..####..#..###.##......#.#...##.##.##.#..#...##...#.####...##.#.#...###..##..##.####