You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2020/17.rkt

58 lines
1.8 KiB
Racket

#lang br
(require racket/file rackunit)
(define grid
(for*/hash ([(row ridx) (in-indexed (file->lines "17.rktd"))]
[(col cidx) (in-indexed row)])
(values (list 0 (make-rectangular cidx ridx)) col)))
(define (seat-count grid)
(count (λ (val) (char=? val #\#)) (hash-values grid)))
(define offsets-3d (for*/list ([z '(1 0 -1)]
[xy '(-1-1i -1 -1+i +i 1+i 1 1-i -i 0)]
#:unless (and (zero? z) (zero? xy)))
(list z xy)))
(define offsets-4d
(for*/list ([offset (cons '(0 0) offsets-3d)]
[zadj '(+i 0 -i)]
[nextval (in-value
(list (+ zadj (first offset)) (second offset)))]
#:unless (equal? nextval '(0 0)))
nextval))
(define (adjacent-occupied-seats grid offsets k)
(for/sum ([offset (in-list offsets)])
(let loop ([k (map + k offset)] [sum 0])
(match (hash-ref grid k #false)
[#\# 1]
[_ 0]))))
(define (grow grid offsets)
(define newgrid (make-hash))
(for* ([k (in-hash-keys grid)]
[offset (cons '(0 0) offsets)])
(define newk (map + k offset))
(hash-ref! newgrid newk (hash-ref grid newk #\.)))
newgrid)
(define (iterate grid offsets)
(for/hash ([(k v) (in-hash (grow grid offsets))])
(match v
[#\# (values k (if (<= 2 (adjacent-occupied-seats grid offsets k) 3) #\# #\.))]
[_ (values k (if (= (adjacent-occupied-seats grid offsets k) 3) #\# #\.))])))
(define (count-active grid)
(count (λ (val) (char=? val #\#)) (hash-values grid)))
(define (solve offsets)
(for/fold ([grid grid]
#:result (count-active grid))
([i 6])
(iterate grid offsets)))
(check-equal? (solve offsets-3d) 395)
;; warning: slow
#;(check-equal? (solve offsets-4d) 2296)