aboutsummaryrefslogtreecommitdiff
path: root/2022
diff options
context:
space:
mode:
authorHunky Jimpjorps <thechairman@thechairman.info>2022-12-14 12:46:34 -0500
committerHunky Jimpjorps <thechairman@thechairman.info>2022-12-14 12:46:34 -0500
commit35e350d736d73dbbfe2505d3fc3bda7e7ca120ea (patch)
tree77c687644b63485d8df67f5c478b17bef28573ee /2022
parent9384f349e3fe5d422141bf64be05e7ae477c99f0 (diff)
downloadgleam_aoc-35e350d736d73dbbfe2505d3fc3bda7e7ca120ea.tar.gz
gleam_aoc-35e350d736d73dbbfe2505d3fc3bda7e7ca120ea.zip
day 14 tweaks
Diffstat (limited to '2022')
-rw-r--r--2022/day-14/day-14.rkt75
1 files changed, 30 insertions, 45 deletions
diff --git a/2022/day-14/day-14.rkt b/2022/day-14/day-14.rkt
index 7950339..c6b5c88 100644
--- a/2022/day-14/day-14.rkt
+++ b/2022/day-14/day-14.rkt
@@ -8,57 +8,42 @@
(define (trace-line-between-points p1 p2)
(match* (p1 p2)
- [((list x y1) (list x y2))
- (for/list ([y [in-inclusive-range (min y1 y2) (max y1 y2)]])
- (cons x y))]
- [((list x1 y) (list x2 y))
- (for/list ([x [in-inclusive-range (min x1 x2) (max x1 x2)]])
- (cons x y))]))
+ [((list x y1) (list x y2)) (map (λ (y) (cons x y)) (inclusive-range (min y1 y2) (max y1 y2)))]
+ [((list x1 y) (list x2 y)) (map (λ (x) (cons x y)) (inclusive-range (min x1 x2) (max x1 x2)))]))
-(define all-coordinates
- (apply append
- (for/list ([formation (in-list (string-split data "\n"))])
- (define coord-list
- (for/list ([coord-pair (in-list (string-split formation " -> "))])
- (for/list ([coord (in-list (string-split coord-pair ","))])
- (string->number coord))))
- (apply append (adjacent-map trace-line-between-points coord-list)))))
+(define (find-points-in-structure str)
+ (define endpoints
+ (for/list ([coord-pair (in-list (string-split str " -> "))])
+ (for/list ([coord (in-list (string-split coord-pair ","))])
+ (string->number coord))))
+ (~>> endpoints (adjacent-map trace-line-between-points) (apply append) (list->set)))
-(define rock-structures-hash
- (for/hash ([p (in-list all-coordinates)])
- (values p 'rock)))
+(define blocked-locations
+ (~> data (string-split "\n") (map find-points-in-structure _) (apply set-union _)))
-(define max-vertical-distance (~>> all-coordinates (argmax cdr) cdr add1))
+(define max-vertical-distance (~>> blocked-locations (set->list) (argmax cdr) cdr add1))
-(define (open? h x y)
- (not (hash-has-key? h (cons x y))))
+(define (open? pts p)
+ (not (set-member? pts p)))
;; part 1
-(define (trace-grain h [pos (cons 500 0)])
- (match-define (cons x y) pos)
+(define (trace-grain pts [pt (cons 500 0)] #:at-limit do-at-limit)
+ (match-define (cons x y) pt)
(cond
- [(> y max-vertical-distance) 'break]
- [(open? h x (add1 y)) (trace-grain h (cons x (add1 y)))]
- [(open? h (sub1 x) (add1 y)) (trace-grain h (cons (sub1 x) (add1 y)))]
- [(open? h (add1 x) (add1 y)) (trace-grain h (cons (add1 x) (add1 y)))]
- [else (hash-set h (cons x y) 'sand)]))
-
-(for/fold ([h rock-structures-hash] [grains 0] #:result grains) ([_ (in-naturals 1)])
- (define h* (trace-grain h))
- #:break (eq? h* 'break)
- (values h* (add1 grains)))
+ [(>= y max-vertical-distance) (do-at-limit pts pt)]
+ [(ormap (λ (d)
+ (let ([p* (cons (+ x d) (add1 y))])
+ (if (open? pts p*) (trace-grain pts p* #:at-limit do-at-limit) #f)))
+ '(0 -1 1))]
+ [else (set-add pts pt)]))
+
+(for/fold ([pts blocked-locations] [grains 0] #:result grains) ([_ (in-naturals 1)])
+ (define pts* (trace-grain pts #:at-limit (const 'break)))
+ #:break (equal? pts* 'break)
+ (values pts* (add1 grains)))
;; part 2
-(define (trace-grain* h [pos (cons 500 0)])
- (match-define (cons x y) pos)
- (cond
- [(= y max-vertical-distance) (hash-set h (cons x y) 'sand)]
- [(open? h x (add1 y)) (trace-grain* h (cons x (add1 y)))]
- [(open? h (sub1 x) (add1 y)) (trace-grain* h (cons (sub1 x) (add1 y)))]
- [(open? h (add1 x) (add1 y)) (trace-grain* h (cons (add1 x) (add1 y)))]
- [else (hash-set h (cons x y) 'sand)]))
-
-(for/fold ([h rock-structures-hash] [grains 0] #:result grains) ([_ (in-naturals 1)])
- #:break (not (open? h 500 0))
- (define h* (trace-grain* h))
- (values h* (add1 grains)))
+(for/fold ([pts blocked-locations] [grains 0] #:result grains) ([_ (in-naturals 1)])
+ #:break (not (open? pts (cons 500 0)))
+ (define pts* (trace-grain pts #:at-limit set-add))
+ (values pts* (add1 grains)))