day 17: some cleanup but idk how to make it better
This commit is contained in:
parent
61f870ddac
commit
357a58b55f
119
17.rkt
119
17.rkt
|
@ -5,85 +5,68 @@
|
||||||
;; solution for day 17
|
;; solution for day 17
|
||||||
|
|
||||||
(struct pt [x y z w] #:transparent)
|
(struct pt [x y z w] #:transparent)
|
||||||
|
(define pt-getters (list pt-x pt-y pt-z pt-w))
|
||||||
|
|
||||||
(define (part1 input)
|
(define (pt+ . args)
|
||||||
(define world (hash-copy input))
|
(for/fold ([ans (pt 0 0 0 0)]) ([x (in-list args)])
|
||||||
(define (simulate world)
|
(apply pt (map #{+ (% ans) (% x)} pt-getters))))
|
||||||
(define new-world (make-hash))
|
|
||||||
(define min-x (apply min (map pt-x (hash-keys world))))
|
|
||||||
(define max-x (apply max (map pt-x (hash-keys world))))
|
|
||||||
(define min-y (apply min (map pt-y (hash-keys world))))
|
|
||||||
(define max-y (apply max (map pt-y (hash-keys world))))
|
|
||||||
(define min-z (apply min (map pt-z (hash-keys world))))
|
|
||||||
(define max-z (apply max (map pt-z (hash-keys world))))
|
|
||||||
(for* ([x (in-range (- min-x 1) (+ max-x 2))]
|
|
||||||
[y (in-range (- min-y 1) (+ max-y 2))]
|
|
||||||
[z (in-range (- min-z 1) (+ max-z 2))])
|
|
||||||
(define ct (for*/sum ([dx (in-range -1 2)]
|
|
||||||
[dy (in-range -1 2)]
|
|
||||||
[dz (in-range -1 2)]
|
|
||||||
#:unless (and (zero? dx) (zero? dy) (zero? dz))
|
|
||||||
#:when (hash-ref world (pt (+ x dx) (+ y dy) (+ z dz) 0) #f))
|
|
||||||
1))
|
|
||||||
(define this (pt x y z 0))
|
|
||||||
(cond
|
|
||||||
[(hash-ref world this #f)
|
|
||||||
(when (or (= 2 ct) (= 3 ct))
|
|
||||||
(hash-set! new-world this #t))]
|
|
||||||
[else
|
|
||||||
(when (= 3 ct)
|
|
||||||
(hash-set! new-world this #t))]))
|
|
||||||
new-world)
|
|
||||||
|
|
||||||
(for ([i (in-range 6)])
|
(define (in-pts lower upper use-w?)
|
||||||
(set! world (simulate world)))
|
(define (in-range+ getter)
|
||||||
(length (filter identity (hash-values world))))
|
(in-range (sub1 (getter lower)) (+ 2 (getter upper))))
|
||||||
|
(for*/stream ([x (in-range+ pt-x)]
|
||||||
|
[y (in-range+ pt-y)]
|
||||||
|
[z (in-range+ pt-z)]
|
||||||
|
[w (if use-w? (in-range+ pt-w) (in-range 1))])
|
||||||
|
(pt x y z w)))
|
||||||
|
|
||||||
(define (part2 input)
|
(define nearby/4d
|
||||||
(define world (hash-copy input))
|
(for*/list ([x (in-range -1 2)]
|
||||||
(define (simulate world)
|
[y (in-range -1 2)]
|
||||||
(define new-world (make-hash))
|
[z (in-range -1 2)]
|
||||||
(define min-x (apply min (map pt-x (hash-keys world))))
|
[w (in-range -1 2)]
|
||||||
(define max-x (apply max (map pt-x (hash-keys world))))
|
#:unless (and (zero? x) (zero? y) (zero? z) (zero? w)))
|
||||||
(define min-y (apply min (map pt-y (hash-keys world))))
|
(pt x y z w)))
|
||||||
(define max-y (apply max (map pt-y (hash-keys world))))
|
|
||||||
(define min-z (apply min (map pt-z (hash-keys world))))
|
|
||||||
(define max-z (apply max (map pt-z (hash-keys world))))
|
|
||||||
(define min-w (apply min (map pt-w (hash-keys world))))
|
|
||||||
(define max-w (apply max (map pt-w (hash-keys world))))
|
|
||||||
(for* ([x (in-range (- min-x 1) (+ max-x 2))]
|
|
||||||
[y (in-range (- min-y 1) (+ max-y 2))]
|
|
||||||
[z (in-range (- min-z 1) (+ max-z 2))]
|
|
||||||
[w (in-range (- min-w 1) (+ max-w 2))])
|
|
||||||
(define ct (for*/sum ([dx (in-range -1 2)]
|
|
||||||
[dy (in-range -1 2)]
|
|
||||||
[dz (in-range -1 2)]
|
|
||||||
[dw (in-range -1 2)]
|
|
||||||
#:unless (and (zero? dx) (zero? dy) (zero? dz) (zero? dw))
|
|
||||||
#:when (hash-ref world (pt (+ x dx) (+ y dy) (+ z dz) (+ w dw)) #f))
|
|
||||||
1))
|
|
||||||
(define this (pt x y z w))
|
|
||||||
(cond
|
|
||||||
[(hash-ref world this #f)
|
|
||||||
(when (or (= 2 ct) (= 3 ct))
|
|
||||||
(hash-set! new-world this #t))]
|
|
||||||
[else
|
|
||||||
(when (= 3 ct)
|
|
||||||
(hash-set! new-world this #t))]))
|
|
||||||
new-world)
|
|
||||||
|
|
||||||
(for ([i (in-range 6)])
|
(define nearby/3d (filter #{zero? (pt-w %)} nearby/4d))
|
||||||
(set! world (simulate world)))
|
|
||||||
(length (filter identity (hash-values world))))
|
(define (calc-bounds world)
|
||||||
|
(define (helper getter reducer)
|
||||||
|
(apply reducer (set-map world getter)))
|
||||||
|
(define (helper2 reducer)
|
||||||
|
(apply pt (map #{helper % reducer} pt-getters)))
|
||||||
|
(values (helper2 min) (helper2 max)))
|
||||||
|
|
||||||
|
(define (simulate world use-w?)
|
||||||
|
(define new-world (mutable-set))
|
||||||
|
(define-values [lower upper] (calc-bounds world))
|
||||||
|
(define nearby (if use-w? nearby/4d nearby/3d))
|
||||||
|
|
||||||
|
(for ([pt (in-pts lower upper use-w?)])
|
||||||
|
(define ct
|
||||||
|
(for*/sum ([nb (in-list nearby)])
|
||||||
|
(if (set-member? world (pt+ pt nb)) 1 0)))
|
||||||
|
(when (if (set-member? world pt) (<= 2 ct 3) (= 3 ct))
|
||||||
|
(set-add! new-world pt)))
|
||||||
|
|
||||||
|
new-world)
|
||||||
|
|
||||||
|
(define (simulate/times world times use-w?)
|
||||||
|
(set-count
|
||||||
|
(for/fold ([world world]) ([_ (in-range times)])
|
||||||
|
(simulate world use-w?))))
|
||||||
|
|
||||||
|
(define part1 #{simulate/times % 6 #f})
|
||||||
|
(define part2 #{simulate/times % 6 #t})
|
||||||
|
|
||||||
;; parse input file
|
;; parse input file
|
||||||
(define (parse fname)
|
(define (parse fname)
|
||||||
(define input (file->lines fname))
|
(define input (file->lines fname))
|
||||||
(define world (make-hash))
|
(define world (mutable-set))
|
||||||
(for ([line (in-list input)] [y (in-naturals)])
|
(for ([line (in-list input)] [y (in-naturals)])
|
||||||
(for ([char (in-string line)] [x (in-naturals)])
|
(for ([char (in-string line)] [x (in-naturals)])
|
||||||
(when (char=? #\# char)
|
(when (char=? #\# char)
|
||||||
(hash-set! world (pt x y 0 0) #t))))
|
(set-add! world (pt x y 0 0)))))
|
||||||
world)
|
world)
|
||||||
|
|
||||||
(module+ test
|
(module+ test
|
||||||
|
|
Loading…
Reference in New Issue