diff options
author | H.J <thechairman@thechairman.info> | 2024-10-09 11:36:55 -0400 |
---|---|---|
committer | H.J <thechairman@thechairman.info> | 2024-10-09 11:36:55 -0400 |
commit | 8777ff071f7bb37631baa7b6717ad29961e50911 (patch) | |
tree | 6d59c4ed58e454b960339c3d1151f0a879e8d7cb /racket/aoc2023/day-10 | |
parent | 6156a9ef7be4012063a042aafb4e9b0d7eadde8e (diff) | |
download | gleam_aoc-8777ff071f7bb37631baa7b6717ad29961e50911.tar.gz gleam_aoc-8777ff071f7bb37631baa7b6717ad29961e50911.zip |
sorting by language
Diffstat (limited to 'racket/aoc2023/day-10')
-rw-r--r-- | racket/aoc2023/day-10/day-10.rkt | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/racket/aoc2023/day-10/day-10.rkt b/racket/aoc2023/day-10/day-10.rkt new file mode 100644 index 0000000..64d8727 --- /dev/null +++ b/racket/aoc2023/day-10/day-10.rkt @@ -0,0 +1,97 @@ +#lang racket + +(require advent-of-code + threading) + +(struct posn (r c) #:transparent) + +(define/match (add-posns _p1 _p2) + [((posn x1 y1) (posn x2 y2)) (posn (+ x1 x2) (+ y1 y2))]) + +(define go-north (posn -1 0)) +(define go-south (posn 1 0)) +(define go-east (posn 0 1)) +(define go-west (posn 0 -1)) + +(define initial-directions + (list (cons go-north '(#\| #\7 #\F)) + (cons go-south '(#\| #\J #\L)) + (cons go-east '(#\- #\J #\7)) + (cons go-west '(#\- #\F #\L)))) + +(define/match (pipe-neighbors _pipe) + [(#\|) (list go-north go-south)] + [(#\-) (list go-east go-west)] + [(#\L) (list go-north go-east)] + [(#\F) (list go-south go-east)] + [(#\7) (list go-south go-west)] + [(#\J) (list go-north go-west)]) + +(define (make-pipe-grid in) + (for*/hash ([(row r) (in-indexed (string-split in "\n"))] + [(ch c) (in-indexed (string->list row))]) + (values (posn (add1 r) (add1 c)) ch))) + +(define (get-valid-S-neighbors S grid) + (for/list ([dir (in-list initial-directions)] + #:do [(match-define (cons d valid) dir)] + #:do [(define neighbor (add-posns d S))] + #:when (member (hash-ref grid neighbor 'none) valid)) + neighbor)) + +(define (to-next-pipe current previous grid [acc '()]) + (cond + [(equal? (hash-ref grid current #f) #\S) acc] + [else + (define next + (for/first ([d (in-list (pipe-neighbors (hash-ref grid current)))] + #:do [(define neighbor (add-posns d current))] + #:unless (equal? neighbor previous)) + neighbor)) + (~> next (to-next-pipe _ current grid (cons current acc)))])) + +;; part 1 +(define input (fetch-aoc-input (find-session) 2023 10 #:cache #true)) + +(define pipe-grid (make-pipe-grid input)) + +(define S-posn + (for/first ([(k v) (in-hash pipe-grid)] #:when (equal? v #\S)) + k)) + +(define S-neighbors (get-valid-S-neighbors S-posn pipe-grid)) + +(define pipe-loop (to-next-pipe (first S-neighbors) S-posn pipe-grid '())) + +(/ (add1 (length pipe-loop)) 2) + +;; part 2 +(define pipe-loop-set (~> (list->set pipe-loop) (set-add S-posn))) + +(define (trace-rays pt pipes grid) + (cond + [(set-member? pipes pt) #f] + [else (odd? (trace-ray pt pipes grid))])) + +(define (trace-ray pt pipes grid) + (define row (posn-r pt)) + (for/fold ([acc 0] + [corner #f] + #:result acc) + ([col (in-naturals (posn-c pt))] + #:do [(define test-pt (posn row col))] + #:break (not (hash-has-key? grid test-pt)) + #:when (set-member? pipes test-pt)) + (define pipe (hash-ref grid test-pt)) + (match* (corner pipe) + [(#f #\|) (values (add1 acc) #f)] ; vertical crossing + [(#f (or #\F #\L)) (values acc pipe)] + [(#\F #\J) (values (add1 acc) #f)] ; a ┏━┛ shape counts as a vertical crossing + [(#\L #\7) (values (add1 acc) #f)] + [(#\F #\7) (values acc #f)] ; a ┏━┓ shape doesn't count + [(#\L #\J) (values acc #f)] + [(_ _) (values acc corner)]))) + +(~> pipe-grid + hash-keys + (count (λ~> (trace-rays pipe-loop-set pipe-grid)) _)) |