58 lines
1.7 KiB
Racket
58 lines
1.7 KiB
Racket
#lang racket/base
|
|
|
|
(require racket/list
|
|
racket/set)
|
|
|
|
(module+ test
|
|
(require rackunit))
|
|
|
|
(define (read-input filename dimension)
|
|
(with-input-from-file filename
|
|
(lambda ()
|
|
(for/set ([line (in-lines)]
|
|
[i (in-naturals)]
|
|
#:when #t
|
|
[c (in-list (string->list line))]
|
|
[j (in-naturals)]
|
|
#:when (eq? c #\#))
|
|
(append (list i j) (make-list (- dimension 2) 0))))))
|
|
|
|
(define (neighbours pos)
|
|
(define dim (length pos))
|
|
(define relative (remove (make-list dim 0) (apply cartesian-product (make-list dim '(-1 0 1)))))
|
|
(map (λ (rel) (map + pos rel)) relative))
|
|
|
|
(define (lives? state pos)
|
|
(define neighbours-count (length (filter (λ (n) (set-member? state n))
|
|
(neighbours pos))))
|
|
(define current (set-member? state pos))
|
|
(or (and current (<= 2 neighbours-count 3))
|
|
(and (not current) (= 3 neighbours-count))))
|
|
|
|
(define (step state)
|
|
(define dim (length (set-first state)))
|
|
(define indexes (flatten (set->list state)))
|
|
(define min-index (sub1 (apply min indexes)))
|
|
(define max-index (+ 2 (apply max indexes)))
|
|
(for/set ([pos (apply cartesian-product (make-list dim (range min-index max-index)))]
|
|
#:when (lives? state pos))
|
|
pos))
|
|
|
|
(define (power n f)
|
|
(apply compose (make-list n f)))
|
|
|
|
(define (part1 filename)
|
|
(define input (read-input filename 3))
|
|
(set-count ((power 6 step) input)))
|
|
|
|
(define (part2 filename)
|
|
(define input (read-input filename 4))
|
|
(set-count ((power 6 step) input)))
|
|
|
|
(module+ test
|
|
(check-equal? (part1 "test") 112)
|
|
(check-equal? (part2 "test") 848))
|
|
|
|
(module+ main
|
|
(displayln (part1 "input"))
|
|
(displayln (part2 "input")))
|