1
0
Fork 0

Day 3: Cleaned up a bit.

This commit is contained in:
Jonathan Chan 2019-12-12 13:02:35 -08:00
parent 301f30268e
commit 23d605ab45
1 changed files with 71 additions and 71 deletions

View File

@ -21,21 +21,38 @@
;; - first-visited? : Whether the first wire has traversed the point; ;; - first-visited? : Whether the first wire has traversed the point;
;; - first-steps : How many steps from the origin the first wire has taken; ;; - first-steps : How many steps from the origin the first wire has taken;
;; - second-visited?, second-steps: idem but for the second wire. ;; - second-visited?, second-steps: idem but for the second wire.
(define pos-x car) (define hashtable (make-hash))
(define pos-y cdr)
(define (pos x y)
(cons x y))
(struct point (struct point
(first-visited? (first-visited?
first-steps first-steps
second-visited? second-visited?
second-steps)) second-steps)
#:transparent)
(define origin (pos 0 0))
(define default-point (point #f 0 #f 0)) (define default-point (point #f 0 #f 0))
;; step-path : boolean -> path -> hashtable -> (pos . number) -> (pos . number) (define origin (cons 0 0))
(define (manhattan xy)
(+ (abs (car xy))
(abs (cdr xy))))
(define (update! first-wire? x y count)
(hash-update!
hashtable (cons x y)
(λ (pt)
(if first-wire?
(struct-copy
point pt
[first-visited? #t]
[first-steps count])
(struct-copy
point pt
[second-visited? #t]
[second-steps count])))
default-point)
(add1 count))
;; step-path : boolean -> path -> (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))
@ -43,71 +60,54 @@
;; pos-count : A pair (pos . number) that indicates the current location and the steps taken ;; pos-count : A pair (pos . number) that indicates the current location and the steps taken
;; hashtable : A map from pos to point ;; hashtable : A map from pos to point
;; Returns the new position after stepping ;; Returns the new position after stepping
(define (step-path first-wire? path ht pos-count) (define (step-path! first-wire? path pos-count)
(let* ([position (car pos-count)] (let* ([x (caar pos-count)]
[count (cdr pos-count)] [y (cdar pos-count)]
[x (car position)] [count (cdr pos-count)]
[y (cdr position)] [n (cdr path)])
[update (curry (match (car path)
(λ (dir i count) ['R
(let* ([key (match dir (cons (cons (+ x n) y)
['x (pos i y)] (foldl ( update! first-wire?) count
['y (pos x i)])] (range (add1 x) (add1 (+ x n)))
[value (hash-ref ht key default-point)] (make-list n y)))]
[new-count (add1 count)] ['L
[new-value (cons (cons (- x n) y)
(if first-wire? (foldl ( update! first-wire?) count
(point #t new-count (reverse (range (- x n) x))
(point-second-visited? value) (make-list n y)))]
(point-second-steps value)) ['U
(point (point-first-visited? value) (cons (cons x (+ y n))
(point-first-steps value) (foldl ( update! first-wire?) count
#t new-count))]) (make-list n x)
(hash-set! ht key new-value) (range (add1 y) (add1 (+ y n)))))]
new-count)))]) ['D
(match path (cons (cons x (- y n))
[`(R . ,(? number? n)) (foldl ( update! first-wire?) count
(cons (pos (+ x n) y) (make-list n x)
(foldl (update 'x) count (range (add1 x) (add1 (+ x n)))))] (reverse (range (- y n) y))))])))
[`(L . ,(? number? n))
(cons (pos (- x n) y)
(foldl (update 'x) count (reverse (range (- x n) x))))]
[`(U . ,(? number? n))
(cons (pos x (+ y n))
(foldl (update 'y) count (range (add1 y) (add1 (+ y n)))))]
[`(D . ,(? number? n))
(cons (pos x (- y n))
(foldl (update 'y) count (reverse (range (- y n) y))))])))
(define (step-wire first-wire? wire ht) (define (step-wire! first-wire? wire)
(foldl (λ (path pos-count) (step-path first-wire? path ht pos-count)) `(,origin . 0) wire)) (foldl ( step-path! first-wire?) `(,origin . 1) wire))
(define-values (part1 intersect-points) (define (intersect ht)
(let* ([hashtable (make-hash)] (filter-map
[_ (step-wire #t wire1 hashtable)] (λ (xypt)
[_ (step-wire #f wire2 hashtable)] (define pt (cdr xypt))
[hashlist (hash->list hashtable)] (and (point-first-visited? pt)
[intersections (point-second-visited? pt)
(filter (λ (kv) (cons (car xypt)
(let ([v (cdr kv)]) (+ (point-first-steps pt)
(and (point-first-visited? v) (point-second-steps pt)))))
(point-second-visited? v)))) (hash->list ht)))
hashlist)]
[distances (define-values (part1 part2)
(map (λ (kv) (let* ([_ (step-wire! #t wire1)]
(let ([k (car kv)]) [_ (step-wire! #f wire2)]
(+ (abs (pos-x k)) [intersections (intersect hashtable)]
(abs (pos-y k))))) [distances (map ( manhattan car) intersections)]
intersections)]) [steps (map cdr intersections)])
(values (apply min distances) (values (apply min distances)
(map cdr intersections)))) (apply min steps))))
(define part2
(let* ([steps
(map (λ (v)
(+ (point-first-steps v)
(point-second-steps v)))
intersect-points)])
(apply min steps)))
(show-solution part1 part2) (show-solution part1 part2)