Day 10: Part 2.
This commit is contained in:
parent
fd9e2bade8
commit
80b25a4095
13
lib.rkt
13
lib.rkt
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
(provide problem-input
|
(provide problem-input
|
||||||
show-solution
|
show-solution
|
||||||
|
uncurry
|
||||||
sum
|
sum
|
||||||
neq?
|
neq?
|
||||||
nzero?
|
nzero?
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
list-ref*
|
list-ref*
|
||||||
chunks-of
|
chunks-of
|
||||||
transpose
|
transpose
|
||||||
|
zip
|
||||||
list->queue
|
list->queue
|
||||||
vector-ref*
|
vector-ref*
|
||||||
vector-set!*)
|
vector-set!*)
|
||||||
|
@ -38,6 +40,13 @@
|
||||||
(printf "Part 1: ~a\nPart 2: ~a\n" part1 part2))
|
(printf "Part 1: ~a\nPart 2: ~a\n" part1 part2))
|
||||||
|
|
||||||
|
|
||||||
|
;; Function helpers ;;
|
||||||
|
|
||||||
|
;; uncurry : (a1 -> ... -> an -> b) -> ((listof a) -> b)
|
||||||
|
(define uncurry
|
||||||
|
(curry apply))
|
||||||
|
|
||||||
|
|
||||||
;; Number helpers ;;
|
;; Number helpers ;;
|
||||||
|
|
||||||
;; sum : (listof number) -> number
|
;; sum : (listof number) -> number
|
||||||
|
@ -107,6 +116,10 @@
|
||||||
[layers (map cdr layers)])
|
[layers (map cdr layers)])
|
||||||
(cons pixels (transpose layers)))))
|
(cons pixels (transpose layers)))))
|
||||||
|
|
||||||
|
;; zip : (a1 -> ... -> an -> b) -> (listof a1) -> ... -> (listof an) -> (listof b)
|
||||||
|
(define (zip f . lsts)
|
||||||
|
(map (curry apply f) (transpose lsts)))
|
||||||
|
|
||||||
;; list->queue : (listof any) -> (queueof any)
|
;; list->queue : (listof any) -> (queueof any)
|
||||||
;; Creates a queue and adds elements of list in order
|
;; Creates a queue and adds elements of list in order
|
||||||
(define (list->queue lst)
|
(define (list->queue lst)
|
||||||
|
|
93
src/10.rkt
93
src/10.rkt
|
@ -8,53 +8,66 @@
|
||||||
(define width (string-length (car input)))
|
(define width (string-length (car input)))
|
||||||
(define height (length input))
|
(define height (length input))
|
||||||
|
|
||||||
(define (coprime? ij)
|
(define (out-of-range? x y)
|
||||||
(= 1 (gcd (first ij)
|
(or (< x 0)
|
||||||
(second ij))))
|
(< y 0)
|
||||||
|
(>= x width)
|
||||||
|
(>= y height)))
|
||||||
|
|
||||||
|
(define (coprime? i j)
|
||||||
|
(= 1 (gcd i j)))
|
||||||
|
|
||||||
(define (offsets x y)
|
(define (offsets x y)
|
||||||
(define is
|
(let ([is (range (negate x) (- width x))]
|
||||||
(range (negate x) (- width x)))
|
[js (range (negate y) (- height y))])
|
||||||
(define js
|
(filter (uncurry coprime?) (cartesian-product is js))))
|
||||||
(range (negate y) (- height y)))
|
|
||||||
(filter coprime? (cartesian-product is js)))
|
|
||||||
|
|
||||||
(define (asteroid? xy)
|
(define (asteroid? x y)
|
||||||
(define row (list-ref input (second xy)))
|
(define row (list-ref input y))
|
||||||
(eq? #\# (string-ref row (first xy))))
|
(eq? #\# (string-ref row x)))
|
||||||
|
|
||||||
(define (asteroid-offset? x y ij)
|
(define (asteroid-offset x y i j)
|
||||||
(define i (first ij))
|
(let loop ([m 1])
|
||||||
(define j (second ij))
|
(let ([x* (+ x (* i m))]
|
||||||
(define max-multiple
|
[y* (+ y (* j m))])
|
||||||
(let ([max-x
|
|
||||||
(cond
|
(cond
|
||||||
[(zero? i) width]
|
[(out-of-range? x* y*) #f]
|
||||||
[(positive? i) (truncate (/ (- (sub1 width) x) i))]
|
[(asteroid? x* y*) (list x* y*)]
|
||||||
[else (abs (truncate (/ x i)))])]
|
[else (loop (add1 m))]))))
|
||||||
[max-y
|
|
||||||
(cond
|
|
||||||
[(zero? j) height]
|
|
||||||
[(positive? j) (truncate (/ (- (sub1 height) y) j))]
|
|
||||||
[else (abs (truncate (/ y j)))])])
|
|
||||||
(min max-x max-y)))
|
|
||||||
(ormap (λ (m) (asteroid? `(,(+ x (* m i))
|
|
||||||
,(+ y (* m j)))))
|
|
||||||
(range 1 (add1 max-multiple))))
|
|
||||||
|
|
||||||
(define (asteroids xy)
|
(define (asteroids x y)
|
||||||
(define x (first xy))
|
(filter-map (uncurry (curry asteroid-offset x y)) (offsets x y)))
|
||||||
(define y (second xy))
|
|
||||||
(count (curry asteroid-offset? x y) (offsets x y)))
|
|
||||||
|
|
||||||
(define-values (part1 location)
|
(define-values (part1 location in-view)
|
||||||
(let* ([cols (range width)]
|
(let* ([cols (range width)]
|
||||||
[rows (range height)]
|
[rows (range height)]
|
||||||
[locations (filter asteroid? (cartesian-product cols rows))]
|
[locations (filter (uncurry asteroid?) (cartesian-product cols rows))]
|
||||||
[asteroid-counts (map asteroids locations)]
|
[in-views (map (uncurry asteroids) locations)]
|
||||||
[maximum (apply max asteroid-counts)]
|
[counts (map length in-views)]
|
||||||
[index (index-of asteroid-counts maximum)]
|
[maximum (apply max counts)]
|
||||||
[location (list-ref locations index)])
|
[index (index-of counts maximum)])
|
||||||
(values maximum location)))
|
(values maximum
|
||||||
|
(list-ref locations index)
|
||||||
|
(list-ref in-views index))))
|
||||||
|
|
||||||
(show-solution part1 #f)
|
(define (offset<? xy1 xy2)
|
||||||
|
(let ([x1 (first xy1)]
|
||||||
|
[y1 (second xy1)]
|
||||||
|
[x2 (first xy2)]
|
||||||
|
[y2 (second xy2)])
|
||||||
|
(or ; (0, -) < (+, y) < (0, +) < (-, y)
|
||||||
|
(and (zero? x1) (negative? y1))
|
||||||
|
(and (positive? x1)
|
||||||
|
(or (negative? x2)
|
||||||
|
(and (zero? x2) (positive? y2))))
|
||||||
|
(and (zero? x1) (negative? x2))
|
||||||
|
(and (nzero? x1) (nzero? x2)
|
||||||
|
(< (atan (/ y1 x1)) (atan (/ y2 x2)))))))
|
||||||
|
|
||||||
|
(define part2
|
||||||
|
(let* ([offsets (map (λ (ast) (zip - ast location)) in-view)]
|
||||||
|
[offsets (sort offsets offset<?)]
|
||||||
|
[200th (zip + location (list-ref offsets (sub1 200)))])
|
||||||
|
(+ (* (first 200th) 100) (second 200th))))
|
||||||
|
|
||||||
|
(show-solution part1 part2)
|
Loading…
Reference in New Issue