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/24.rkt

61 lines
1.7 KiB
Racket

4 years ago
#lang br
(require racket/file rackunit)
(define (lex-1 port)
(match (regexp-match #rx"^se|nw|sw|ne|w|e" port)
[#false eof]
[(list str) str]))
(define tokss (for/list ([ln (in-list (file->lines "24.rktd"))])
(for/list ([tok (in-port lex-1 (open-input-string ln))])
tok)))
(define (tok->delta tok)
(match tok
[#"w" -1]
[#"e" 1]
[#"nw" -i]
[#"ne" 1-i]
[#"sw" -1+i]
[#"se" +i]))
(define white -1)
(define black 1)
(define black? positive?)
(define (make-initial-floor tokss)
(define floor (make-hasheqv))
(for ([toks (in-list tokss)])
(hash-update! floor (apply + (map tok->delta toks)) - white))
floor)
(define deltas '(1 -1 -i 1-i -1+i +i))
(define (grow! floor)
(for* ([k (in-list (hash-keys floor))]
[delta (in-list deltas)])
(hash-ref! floor (+ k delta) white)))
(define (adjacent-black-tiles floor k)
(for/sum ([delta (in-list deltas)]
#:when (black? (hash-ref floor (+ k delta) white)))
1))
(define (iterate floor num)
(for ([i (in-range num)])
(grow! floor)
(define fliplist
(for/list ([(k v) (in-hash floor)]
#:when (let ([abt (adjacent-black-tiles floor k)])
(cond
[(and (black? v) (or (zero? abt) (< 2 abt)))]
[(and (not (black? v)) (= 2 abt))]
[else #false])))
k))
(for ([k (in-list fliplist)])
(hash-update! floor k -)))
floor)
(define floor (make-initial-floor tokss))
(check-equal? (count black? (hash-values floor)) 436)
(check-equal? (count black? (hash-values (iterate floor 100))) 4133)