Abstracted message-printing from days 11 and 8; Added fancy symbols for currying, uncurrying, and composition.

This commit is contained in:
Jonathan Chan 2019-12-11 13:54:01 -08:00
parent ce29e2e206
commit 154b2f33ed
5 changed files with 52 additions and 32 deletions

28
lib.rkt
View File

@ -9,6 +9,8 @@
(provide problem-input (provide problem-input
show-solution show-solution
show-msg
$
uncurry uncurry
sum sum
neq? neq?
@ -25,6 +27,17 @@
vector-ref* vector-ref*
vector-set!*) vector-set!*)
;; Function helpers ;;
(define compose)
(define curry)
;; uncurry : (a1 -> ... -> an -> b) -> ((listof a) -> b)
(define uncurry
(curry apply))
(define $ uncurry)
;; IO helpers ;; ;; IO helpers ;;
;; problem-input : number? -> (listof string?) ;; problem-input : number? -> (listof string?)
@ -39,12 +52,15 @@
(define (show-solution part1 part2) (define (show-solution part1 part2)
(printf "Part 1: ~a\nPart 2: ~a\n" part1 part2)) (printf "Part 1: ~a\nPart 2: ~a\n" part1 part2))
;; show-msg : (hashof (a => char)) -> (listof (listof a)) -> void
;; Function helpers ;; ;; Given a grid of values, show the grid line by line,
;; with values replaced by characters in the given hash.
;; uncurry : (a1 -> ... -> an -> b) -> ((listof a) -> b) (define (show-msg char-hash msg)
(define uncurry (for-each
(curry apply)) displayln
(map ( list->string
( map ( hash-ref char-hash)))
msg)))
;; Number helpers ;; ;; Number helpers ;;

View File

@ -20,17 +20,17 @@
(apply max (append (map amplify phases))))) (apply max (append (map amplify phases)))))
(define (amplify-loop phase) (define (amplify-loop phase)
(let* ([amps (map (curry resume-with-input (exec input)) phase)] (let* ([amps (map ( resume-with-input (exec input)) phase)]
[Q (list->queue amps)]) [Q (list->queue amps)])
(let loop ([signal 0]) (let loop ([signal 0])
(define amp (dequeue! Q)) (define amp (dequeue! Q))
(type-case state amp (type-case state amp
[halt (_) signal] [halt (_) signal]
[in (resume) [in (resume)
(define-values (signal st) (define-values (signal* st)
(resume-with-output (resume signal))) (resume-with-output (resume signal)))
(enqueue! Q st) (enqueue! Q st)
(loop signal)] (loop signal*)]
[else (error "amplify-loop: Unexpected program state.")])))) [else (error "amplify-loop: Unexpected program state.")]))))
(define part2 (define part2

View File

@ -8,23 +8,24 @@
(define width 25) (define width 25)
(define height 6) (define height 6)
(define pixel-hash
(make-hash '((#\0 . #\ ) (#\1 . #\█))))
(define layers (define layers
(let* ([area (* width height)] (let* ([area (* width height)]
[chars (string->list input)]) [chars (string->list input)])
(chunks-of chars area))) (chunks-of chars area)))
(define part1 (define part1
(let* ([zeroes (map (curry count (curry eq? #\0)) layers)] (let* ([zeroes (map ( count ( eq? #\0)) layers)]
[min-index (index-of zeroes (apply min zeroes))] [min-index (index-of zeroes (apply min zeroes))]
[min-layer (list-ref layers min-index)] [min-layer (list-ref layers min-index)]
[ones (count (curry eq? #\1) min-layer)] [ones (count ( eq? #\1) min-layer)]
[twos (count (curry eq? #\2) min-layer)]) [twos (count ( eq? #\2) min-layer)])
(* ones twos))) (* ones twos)))
(define part2 (define part2
(let* ([image (map (curry findf (curry neq? #\2)) (transpose layers))] (let* ([image (map ( findf ( neq? #\2)) (transpose layers))])
[image* (map (λ (pixel) (if (eq? pixel #\1) #\█ #\ )) image)] (show-msg pixel-hash (chunks-of image width))))
[msg (map list->string (chunks-of image* width))])
(for-each displayln msg)))
(show-solution part1 #f) (show-solution part1 #f)

View File

@ -20,7 +20,7 @@
(define (offsets x y) (define (offsets x y)
(let ([is (range (negate x) (- width x))] (let ([is (range (negate x) (- width x))]
[js (range (negate y) (- height y))]) [js (range (negate y) (- height y))])
(filter (uncurry coprime?) (cartesian-product is js)))) (filter ($ coprime?) (cartesian-product is js))))
(define (asteroid? x y) (define (asteroid? x y)
(define row (list-ref input y)) (define row (list-ref input y))
@ -36,13 +36,13 @@
[else (loop (add1 m))])))) [else (loop (add1 m))]))))
(define (asteroids x y) (define (asteroids x y)
(filter-map (uncurry (curry asteroid-offset x y)) (offsets x y))) (filter-map ($ ( asteroid-offset x y)) (offsets x y)))
(define-values (part1 location in-view) (define-values (part1 location in-view)
(let* ([cols (range width)] (let* ([cols (range width)]
[rows (range height)] [rows (range height)]
[locations (filter (uncurry asteroid?) (cartesian-product cols rows))] [locations (filter ($ asteroid?) (cartesian-product cols rows))]
[in-views (map (uncurry asteroids) locations)] [in-views (map ($ asteroids) locations)]
[counts (map length in-views)] [counts (map length in-views)]
[maximum (apply max counts)] [maximum (apply max counts)]
[index (index-of counts maximum)]) [index (index-of counts maximum)])

View File

@ -6,6 +6,13 @@
(define input (define input
(string->program (car (problem-input 11)))) (string->program (car (problem-input 11))))
;; 0 is a "black" panel and 1 is a "white" panel
;; but the spaceship is entirely black
;; so the identifier colour is in "white"
;; which we show as black blocks against white
(define panel-hash
(make-hash '((0 . #\ ) (1 . #\█))))
;; The hull as a hash (x . y) -> c ;; The hull as a hash (x . y) -> c
;; x increases rightward ;; x increases rightward
;; y increases downward ;; y increases downward
@ -17,7 +24,7 @@
(define (make-grid xrange yrange) (define (make-grid xrange yrange)
(build-vector (build-vector
(add1 yrange) (add1 yrange)
(λ (_) (make-vector (add1 xrange) #\ )))) (λ (_) (make-vector (add1 xrange)))))
;; Turn CCW if δ = 0, CW if δ = 1 ;; Turn CCW if δ = 0, CW if δ = 1
(define (update-dir dir δ) (define (update-dir dir δ)
@ -67,16 +74,12 @@
[ymin (apply min ys)] [ymax (apply max ys)] [ymin (apply min ys)] [ymax (apply max ys)]
[xrange (- xmax xmin)] [yrange (- ymax ymin)] [xrange (- xmax xmin)] [yrange (- ymax ymin)]
[grid (make-grid xrange yrange)]) [grid (make-grid xrange yrange)])
(for-each (hash-for-each
(λ (kv) hull
(let* ([x (- (caar kv) xmin)] (λ (xy c)
[y (- (cdar kv) ymin)] (let* ([x (- (car xy) xmin)]
[c (cdr kv)] [y (- (cdr xy) ymin)])
[row (vector-ref grid y)]) (vector-set! (vector-ref grid y) x c))))
(cond [(= c 1) (vector-set! row x #\█)]))) (show-msg panel-hash (map vector->list (vector->list grid)))))
(hash->list hull))
(for-each
(λ (row) (displayln (list->string (vector->list row))))
(vector->list grid))))
(show-solution (part1) (part2)) (show-solution (part1) (part2))