1
0
Fork 0

Day 24: Part 1 done, part 2 is incorrect.

This commit is contained in:
Jonathan Chan 2019-12-24 01:00:53 -08:00
parent 6d6e175548
commit 50609b0ab9
3 changed files with 199 additions and 1 deletions

5
input/24.txt Normal file
View File

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

28
lib.rkt
View File

@ -38,7 +38,10 @@
transpose
list->queue
vector-first
vector-last
vector-ref*
vector-grid-ref*
vector-set!*
hash->vector
vector->hash)
@ -243,6 +246,14 @@
;; Vector helpers ;;
;; vector-first : (vectorof any) -> any
(define (vector-first vec)
(vector-ref vec 0))
;; vector-last : (vectorof any) -> any
(define (vector-last vec)
(vector-ref vec (sub1 (vector-length vec))))
;; vector-ref* : (vectorof any) -> number -> any -> any
;; Same as list-ref, except a default value is provided
;; if the index is beyond the length of the list.
@ -251,9 +262,24 @@
failure-result
(vector-ref vec pos)))
;; vector-grid-ref* : (vectorof (vectorof any)) -> (list number number) -> any -> any
;; Given coordinates (x, y), in the yth vector, find the xth element.
;; If either x or y are beyond the indices of the vectors,
;; return the default value provided.
(define (vector-grid-ref* grid coord failure-result)
(match-let ([(list x y) coord]
[y-len (vector-length grid)])
(if (or (< y 0) (>= y y-len))
failure-result
(let* ([row (vector-ref grid y)]
[x-len (vector-length row)])
(if (or (< x 0) (>= x x-len))
failure-result
(vector-ref row x))))))
;; vector-set!* : (vectorof any) -> number -> any -> (vectorof any)
;; Set the value at given index in a new vector, then return that vector
;; If the index is beyond the length of the vector,
;; If the index is beyond the indices of the vector,
;; a vector that can accomodate that index is returned,
;; with all the original elements and the element at the index set
(define (vector-set!* vec pos v)

167
src/24.rkt Normal file
View File

@ -0,0 +1,167 @@
#lang racket
(require racket/set
"../lib.rkt")
(define input
(problem-input 24))
(define width
(string-length (car input)))
(define height
(length input))
(define mid-x
(round (/ width 2)))
(define mid-y
(round (/ height 2)))
(define vector-grid
(list->vector (map ( list->vector string->list) input)))
(define (make-empty-grid)
(build-vector height (λ (_) (make-vector width #\.))))
(define (outer-edge? coord)
(match-let ([(list x y) coord])
(or (= x 0) (= y 0)
(= x (sub1 width)) (= y (sub1 height)))))
(define (inner-edge? coord)
(match-let ([(list x y) coord])
(or (= x mid-x)
(= y mid-y))))
(define (edge-bugs grid side)
(match side
['U (vector-count ( char=? #\#) (vector-ref grid 0))]
['D (vector-count ( char=? #\#) (vector-ref grid (sub1 height)))]
['L (vector-count ( char=? #\#) (vector-map ( vector-first) grid))]
['R (vector-count ( char=? #\#) (vector-map ( vector-last) grid))]))
(define (edges-bugs? grid)
(!= 0 (+ (edge-bugs grid 'U)
(edge-bugs grid 'D)
(edge-bugs grid 'L)
(edge-bugs grid 'R))))
(define (middle-bug grid side)
(match side
['U (if (char=? #\# (vector-grid-ref* grid (list mid-x (sub1 mid-y)) #\.)) 1 0)]
['D (if (char=? #\# (vector-grid-ref* grid (list mid-x (add1 mid-y)) #\.)) 1 0)]
['L (if (char=? #\# (vector-grid-ref* grid (list (sub1 mid-x) mid-y) #\.)) 1 0)]
['R (if (char=? #\# (vector-grid-ref* grid (list (add1 mid-x) mid-y) #\.)) 1 0)]))
(define (middle-bugs? grid)
(!= 0 (+ (middle-bug grid 'U)
(middle-bug grid 'D)
(middle-bug grid 'L)
(middle-bug grid 'R))))
(define (adjacent-bugs grid coord)
(match-let* ([(list x y) coord]
[U (vector-grid-ref* grid (list x (sub1 y)) #\.)]
[D (vector-grid-ref* grid (list x (add1 y)) #\.)]
[L (vector-grid-ref* grid (list (sub1 x) y) #\.)]
[R (vector-grid-ref* grid (list (add1 x) y) #\.)])
(count ( char=? #\#) (list U D L R))))
(define (adjacent-bugs* grids level coord)
(match-let* ([(list x y) coord]
[grid (list-ref grids level)]
[level-bugs (adjacent-bugs grid coord)])
(cond
[(and (outer-edge? coord) (> level 0))
(let* ([outer-grid (list-ref grids (sub1 level))])
(cond
[(= x 0)
(+ level-bugs (middle-bug outer-grid 'L))]
[(= y 0)
(+ level-bugs (middle-bug outer-grid 'U))]
[(= x (sub1 width))
(+ level-bugs (middle-bug outer-grid 'R))]
[(= y (sub1 height))
(+ level-bugs (middle-bug outer-grid 'D))]))]
[(and (inner-edge? coord) (< level (sub1 (length grids))))
(let* ([inner-grid (list-ref grids (add1 level))])
(cond
[(and (= x mid-x) (< y mid-y))
(+ level-bugs (edge-bugs inner-grid 'U))]
[(and (= x mid-x) (> y mid-y))
(+ level-bugs (edge-bugs inner-grid 'D))]
[(and (= y mid-y) (< x mid-x))
(+ level-bugs (edge-bugs inner-grid 'L))]
[(and (= y mid-y) (> x mid-x))
(+ level-bugs (edge-bugs inner-grid 'R))]
[else level-bugs]))]
[else level-bugs])))
(define (step grid)
(let ([new-grid (make-empty-grid)])
(for ([coord (cartesian-product (range 0 width) (range 0 height))])
(match-let* ([(list x y) coord]
[char (vector-ref (vector-ref grid y) x)]
[bug-count (adjacent-bugs grid coord)]
[next-char
(match char
[#\. #:when (<= 1 bug-count 2) #\#]
[#\# #:when (!= 1 bug-count) #\.]
[else char])])
(vector-set! (vector-ref new-grid y) x next-char)))
new-grid))
(define (step* grids)
(let* ([grids*
(foldl
(λ (level grid grids*)
(let ([new-grid (make-empty-grid)])
(for ([coord (cartesian-product (range 0 width) (range 0 height))])
(match-let* ([(list x y) coord]
[char (vector-ref (vector-ref grid y) x)]
[bug-count (adjacent-bugs* grids level coord)]
[next-char
(match char
[#\. #:when (<= 1 bug-count 2) #\#]
[#\# #:when (!= 1 bug-count) #\.]
[else char])])
(vector-set! (vector-ref new-grid y) x next-char)))
(cons new-grid grids*)))
'() (range 0 (length grids)) grids)]
[grids* (if (edges-bugs? (first grids*))
(cons (make-empty-grid) grids*)
grids*)]
[grids* (if (middle-bugs? (last grids*))
(append grids* (list (make-empty-grid)))
grids*)])
grids*))
(define (biodiversity grid)
(let ([list-grid (append* (map vector->list (vector->list grid)))])
(sum (map (λ (char i)
(if (char=? char #\#)
(expt 2 i) 0))
list-grid (range 0 (length list-grid))))))
(define (total-bugs grids)
(sum (map (λ (grid)
(sum (vector->list (vector-map ( vector-count ( char=? #\#)) grid))))
grids)))
(define part1
(let loop ([grid vector-grid]
[set (set vector-grid)])
(let ([next-grid (step grid)])
(if (set-member? set next-grid)
(biodiversity next-grid)
(loop next-grid (set-add set next-grid))))))
(define part2
(let loop ([count 0]
[grids (list (make-empty-grid) vector-grid (make-empty-grid))])
(if (= count 10)
(total-bugs grids)
(loop (add1 count) (step* grids)))))
(show-solution part1 part2)