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.
58 lines
1.8 KiB
Racket
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) |