1
0
Fork 0
This commit is contained in:
Jonathan Chan 2022-12-17 12:48:29 -08:00
parent b5f7ca2263
commit 92c8a9243f
2 changed files with 135 additions and 0 deletions

1
input/17.txt Normal file

File diff suppressed because one or more lines are too long

134
src/17.rkt Normal file
View File

@ -0,0 +1,134 @@
#lang curly-fn racket
(require "../lib.rkt")
(define input
(first (problem-input 17)))
(define jets (string-length input))
(define tower (apply mutable-set (map #{cons % 0} (inclusive-range 1 7))))
(define (unblocked? x y)
(not (or (set-member? tower (cons x y))
(= x 0) (= x 8) (= y 0))))
(define (can-move-left? n x y)
(match n
[0 (unblocked? (- x 1) y)]
[1 (and (unblocked? x y)
(unblocked? (- x 1) (+ y 1))
(unblocked? x (+ y 2)))]
[2 (and (unblocked? (- x 1) y)
(unblocked? (+ x 1) (+ y 1))
(unblocked? (+ x 1) (+ y 2)))]
[3 (and (unblocked? (- x 1) y)
(unblocked? (- x 1) (+ y 1))
(unblocked? (- x 1) (+ y 2))
(unblocked? (- x 1) (+ y 3)))]
[4 (and (unblocked? (- x 1) y)
(unblocked? (- x 1) (+ y 1)))]))
(define (can-move-right? n x y)
(match n
[0 (unblocked? (+ x 4) y)]
[1 (and (unblocked? (+ x 2) y)
(unblocked? (+ x 3) (+ y 1))
(unblocked? (+ x 2) (+ y 2)))]
[2 (and (unblocked? (+ x 3) y)
(unblocked? (+ x 3) (+ y 1))
(unblocked? (+ x 3) (+ y 2)))]
[3 (and (unblocked? (+ x 1) y)
(unblocked? (+ x 1) (+ y 1))
(unblocked? (+ x 1) (+ y 2))
(unblocked? (+ x 1) (+ y 3)))]
[4 (and (unblocked? (+ x 2) y)
(unblocked? (+ x 2) (+ y 1)))]))
(define (can-fall? n x y)
(match n
[0 (and (unblocked? x (- y 1))
(unblocked? (+ x 1) (- y 1))
(unblocked? (+ x 2) (- y 1))
(unblocked? (+ x 3) (- y 1)))]
[1 (and (unblocked? x y)
(unblocked? (+ x 1) (- y 1))
(unblocked? (+ x 2) y))]
[2 (and (unblocked? x (- y 1))
(unblocked? (+ x 1) (- y 1))
(unblocked? (+ x 2) (- y 1)))]
[3 (unblocked? x (- y 1))]
[4 (and (unblocked? x (- y 1))
(unblocked? (+ x 1) (- y 1)))]))
(define (settle! n x y)
(match n
[0 (set-add! tower `(,x . ,y))
(set-add! tower `(,(+ x 1) . ,y))
(set-add! tower `(,(+ x 2) . ,y))
(set-add! tower `(,(+ x 3) . ,y))]
[1 (set-add! tower `(,(+ x 1) . ,y))
(set-add! tower `(,x . ,(+ y 1)))
(set-add! tower `(,(+ x 1) . ,(+ y 1)))
(set-add! tower `(,(+ x 2) . ,(+ y 1)))
(set-add! tower `(,(+ x 1) . ,(+ y 2)))]
[2 (set-add! tower `(,x . ,y))
(set-add! tower `(,(+ x 1) . ,y))
(set-add! tower `(,(+ x 2) . ,y))
(set-add! tower `(,(+ x 2) . ,(+ y 1)))
(set-add! tower `(,(+ x 2) . ,(+ y 2)))]
[3 (set-add! tower `(,x . ,y))
(set-add! tower `(,x . ,(+ y 1)))
(set-add! tower `(,x . ,(+ y 2)))
(set-add! tower `(,x . ,(+ y 3)))]
[4 (set-add! tower `(,x . ,y))
(set-add! tower `(,(+ x 1) . ,y))
(set-add! tower `(,x . ,(+ y 1)))
(set-add! tower `(,(+ x 1) . ,(+ y 1)))]))
(define (get-height n y)
(match n
[0 y]
[(or 1 2) (+ y 2)]
[3 (+ y 3)]
[4 (+ y 1)]))
(define heights (make-hash))
(define seen (make-hash))
(define candidates (mutable-set))
(define start #f)
(define end #f)
(define part1
(for/fold ([height 0]
[jet 0]
#:result height)
([block (in-range 2022)])
(define b (% block 5))
(unless (and start end)
(if (hash-has-key? seen (cons jet b))
(if (subset? (apply set (range (- block 4) block)) candidates)
(begin (set! start (hash-ref seen (cons jet b))) (set! end block))
(set-add! candidates block))
(hash-set! seen (cons jet b) block)))
(let loop ([x 3]
[y (+ height 4)]
[jet jet])
(define x*
(match (string-ref input jet)
[#\< (if (can-move-left? b x y) (sub1 x) x)]
[#\> (if (can-move-right? b x y) (add1 x) x)]))
(define height* (max height (get-height b y)))
(define jet* (% (add1 jet) jets))
(if (can-fall? b x* y)
(loop x* (sub1 y) jet*)
(begin
(settle! b x* y) ;; add1: number of blocks fallen is offset by 1
(hash-set! heights (add1 block) height*)
(values height* jet*))))))
(define part2
(let-values ([(cycles extra) (quotient/remainder (- 1000000000000 start) (- end start))])
(+ (* (- (hash-ref heights end) (hash-ref heights start)) cycles)
(hash-ref heights (+ start extra)))))
(show-solution part1 part2)