diff options
Diffstat (limited to 'racket/aoc2022/day-17/day-17.rkt')
-rw-r--r-- | racket/aoc2022/day-17/day-17.rkt | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/racket/aoc2022/day-17/day-17.rkt b/racket/aoc2022/day-17/day-17.rkt new file mode 100644 index 0000000..28e8763 --- /dev/null +++ b/racket/aoc2022/day-17/day-17.rkt @@ -0,0 +1,53 @@ +#lang racket + +(require advent-of-code + threading + fancy-app + data/collection) + +(define (relative-rock-coordinates rock) + (for*/hash ([(row y) (in-indexed (reverse rock))] [(_col x) (in-indexed row)]) + (values (cons x y) #true))) + +(define rock-shapes + (~> (open-input-file "./2022/day-17/rock-shapes") + port->string + (string-split "\n\n") + (map (λ~> (string-split _ "\n") (map string->list _) relative-rock-coordinates) _))) + +(define gusts + (~> (fetch-aoc-input (find-session) 2022 17 #:cache #true) + string-trim + string->list + (map (match-lambda + [#\> 1] + [#\< -1]) + _))) + +(define (place-new-rock rock elevation) + (for/hash ([(posn _) (in-hash rock)]) + (match-define (cons x y) posn) + (values (cons (+ x 3) (+ y elevation 4)) #true))) + +(define (gust-move rock wind cave) + (define moved-rock + (for/hash ([(posn _) (in-hash rock)]) + (match-define (cons x y) posn) + (define posn* (cons (+ x wind) y)) + (if (hash-has-key? cave posn) (values 'collision #t) (values posn* #t)))) + (if (hash-has-key? moved-rock 'collision) rock moved-rock)) + +(for/fold ([cave (hash)] + [falling-rock #f] + [top-of-rocks 0] + [rock-cycle (cycle rock-shapes)] + [rock-number 0] + #:result top-of-rocks) + (#:break (> rock-number 2022) [gust (in-cycle gusts)]) + (cond + [(not falling-rock) + (values cave + (~> (first rock-cycle) (place-new-rock top-of-rocks) (gust-move gust cave)) + top-of-rocks + (rest rock-cycle) + (add1 rock-number))])) |