Day 3: Cleanup-ish.
This commit is contained in:
parent
a682d29945
commit
a588c9b2d1
80
src/03.rkt
80
src/03.rkt
|
@ -13,75 +13,101 @@
|
||||||
[wire2 (string->wire (second input))])
|
[wire2 (string->wire (second input))])
|
||||||
(values wire1 wire2)))
|
(values wire1 wire2)))
|
||||||
|
|
||||||
;; step-path : boolean -> path -> (number . number) -> hashtable -> procedure -> (number . number)
|
;; To store the paths of each wire, we will use a hashtable.
|
||||||
|
;; The keys of the hashtable are positions on the grid,
|
||||||
|
;; stored as a pair of numbers (x . y).
|
||||||
|
;; The values of the hashtable are points on the grid,
|
||||||
|
;; which contain four pieces of information:
|
||||||
|
;; - first-visited? : Whether the first wire has traversed the point;
|
||||||
|
;; - first-steps : How many steps from the origin the first wire has taken;
|
||||||
|
;; - second-visited?, second-steps: idem but for the second wire.
|
||||||
|
(define pos-x car)
|
||||||
|
(define pos-y cdr)
|
||||||
|
(define (pos x y)
|
||||||
|
(cons x y))
|
||||||
|
|
||||||
|
(struct point
|
||||||
|
(first-visited?
|
||||||
|
first-steps
|
||||||
|
second-visited?
|
||||||
|
second-steps))
|
||||||
|
|
||||||
|
(define origin (pos 0 0))
|
||||||
|
(define default-point (point #f 0 #f 0))
|
||||||
|
|
||||||
|
;; step-path : boolean -> path -> hashtable -> (pos . number) -> (pos . number)
|
||||||
;; first-wire? : Indicates whether we're stepping for the first or second wire.
|
;; first-wire? : Indicates whether we're stepping for the first or second wire.
|
||||||
;; path : A pair (s: symbol . n: number), where s indicates the direction we step
|
;; path : A pair (s: symbol . n: number), where s indicates the direction we step
|
||||||
;; (R, L, U, D for right (+x), left (-x), up (+y), down (-y))
|
;; (R, L, U, D for right (+x), left (-x), up (+y), down (-y))
|
||||||
;; and n indicates the number of units we step in that direction
|
;; and n indicates the number of units we step in that direction
|
||||||
;; position : A pair (x . y) that indicates the current location
|
;; pos-count : A pair (pos . number) that indicates the current location and the steps taken
|
||||||
;; hashtable : A map from positions to ((boolean . number) . (boolean . number))that indicate
|
;; hashtable : A map from pos to point
|
||||||
;; the total number of steps to get to that position and
|
|
||||||
;; whether the first or second wire has visited that position
|
|
||||||
;; Returns the new position after stepping
|
;; Returns the new position after stepping
|
||||||
(define (step-path first-wire? path pos-count ht)
|
(define (step-path first-wire? path ht pos-count)
|
||||||
(let* ([position (car pos-count)]
|
(let* ([position (car pos-count)]
|
||||||
[count (cdr pos-count)]
|
[count (cdr pos-count)]
|
||||||
[x (car position)]
|
[x (car position)]
|
||||||
[y (cdr position)]
|
[y (cdr position)]
|
||||||
[update (λ (dir)
|
[update (curry
|
||||||
(λ (i count)
|
(λ (dir i count)
|
||||||
(let* ([key (match dir
|
(let* ([key (match dir
|
||||||
['x (cons i y)]
|
['x (pos i y)]
|
||||||
['y (cons x i)])]
|
['y (pos x i)])]
|
||||||
[value (hash-ref ht key '((#f . 0) . (#f . 0)))]
|
[value (hash-ref ht key default-point)]
|
||||||
[new-count (add1 count)]
|
[new-count (add1 count)]
|
||||||
[new-value
|
[new-value
|
||||||
(if first-wire?
|
(if first-wire?
|
||||||
(cons `(#t . ,new-count) (cdr value))
|
(point #t new-count
|
||||||
(cons (car value) `(#t . ,new-count)))])
|
(point-second-visited? value)
|
||||||
|
(point-second-steps value))
|
||||||
|
(point (point-first-visited? value)
|
||||||
|
(point-first-steps value)
|
||||||
|
#t new-count))])
|
||||||
(hash-set! ht key new-value)
|
(hash-set! ht key new-value)
|
||||||
new-count)))])
|
new-count)))])
|
||||||
(match path
|
(match path
|
||||||
[`(R . ,(? number? n))
|
[`(R . ,(? number? n))
|
||||||
(cons (cons (+ x n) y)
|
(cons (pos (+ x n) y)
|
||||||
(foldl (update 'x) count (range (add1 x) (add1 (+ x n)))))]
|
(foldl (update 'x) count (range (add1 x) (add1 (+ x n)))))]
|
||||||
[`(L . ,(? number? n))
|
[`(L . ,(? number? n))
|
||||||
(cons (cons (- x n) y)
|
(cons (pos (- x n) y)
|
||||||
(foldl (update 'x) count (reverse (range (- x n) x))))]
|
(foldl (update 'x) count (reverse (range (- x n) x))))]
|
||||||
[`(U . ,(? number? n))
|
[`(U . ,(? number? n))
|
||||||
(cons (cons x (+ y n))
|
(cons (pos x (+ y n))
|
||||||
(foldl (update 'y) count (range (add1 y) (add1 (+ y n)))))]
|
(foldl (update 'y) count (range (add1 y) (add1 (+ y n)))))]
|
||||||
[`(D . ,(? number? n))
|
[`(D . ,(? number? n))
|
||||||
(cons (cons x (- y n))
|
(cons (pos x (- y n))
|
||||||
(foldl (update 'y) count (reverse (range (- y n) y))))])))
|
(foldl (update 'y) count (reverse (range (- y n) y))))])))
|
||||||
|
|
||||||
(define (step-wire first-wire? wire ht)
|
(define (step-wire first-wire? wire ht)
|
||||||
(foldl (λ (path pos-count) (step-path first-wire? path pos-count ht)) '((0 . 0) . 0) wire))
|
(foldl (λ (path pos-count) (step-path first-wire? path ht pos-count)) `(,origin . 0) wire))
|
||||||
|
|
||||||
(define-values (part1 intersections)
|
(define-values (part1 intersect-points)
|
||||||
(let* ([hashtable (make-hash '(((0 . 0) . ((#f . 0) . (#f . 0)))))]
|
(let* ([hashtable (make-hash)]
|
||||||
[_ (step-wire #t wire1 hashtable)]
|
[_ (step-wire #t wire1 hashtable)]
|
||||||
[_ (step-wire #f wire2 hashtable)]
|
[_ (step-wire #f wire2 hashtable)]
|
||||||
[hashlist (hash->list hashtable)]
|
[hashlist (hash->list hashtable)]
|
||||||
[intersections
|
[intersections
|
||||||
(filter (λ (kv)
|
(filter (λ (kv)
|
||||||
(let ([v (cdr kv)])
|
(let ([v (cdr kv)])
|
||||||
(and (caar v) (cadr v))))
|
(and (point-first-visited? v)
|
||||||
|
(point-second-visited? v))))
|
||||||
hashlist)]
|
hashlist)]
|
||||||
[distances
|
[distances
|
||||||
(map (λ (kv)
|
(map (λ (kv)
|
||||||
(let ([k (car kv)])
|
(let ([k (car kv)])
|
||||||
(+ (abs (car k)) (abs (cdr k)))))
|
(+ (abs (pos-x k))
|
||||||
|
(abs (pos-y k)))))
|
||||||
intersections)])
|
intersections)])
|
||||||
(values (apply min distances)
|
(values (apply min distances)
|
||||||
intersections)))
|
(map cdr intersections))))
|
||||||
|
|
||||||
(define part2
|
(define part2
|
||||||
(let* ([steps
|
(let* ([steps
|
||||||
(map (λ (kv)
|
(map (λ (v)
|
||||||
(let ([v (cdr kv)])
|
(+ (point-first-steps v)
|
||||||
(+ (cdar v) (cddr v))))
|
(point-second-steps v)))
|
||||||
intersections)])
|
intersect-points)])
|
||||||
(apply min steps)))
|
(apply min steps)))
|
||||||
|
|
||||||
(show-solution part1 part2)
|
(show-solution part1 part2)
|
Loading…
Reference in New Issue