aoc2023/3.rkt

74 lines
2.8 KiB
Racket

#lang curly-fn racket
(require "scripts/aoc.rkt")
;; solution for day 3
(define (part1 input)
(define (input-ref grid y x)
(string-ref (vector-ref grid y) x))
(define (symbol-adjacent? grid y x)
(for/or ([delta (in-list '((0 . 1) (1 . 1) (1 . 0)
(1 . -1) (0 . -1) (-1 . -1)
(-1 . 0) (-1 . 1)))]
#:unless (>= (+ (car delta) x) (string-length (vector-ref grid y)))
#:unless (< (+ (car delta) x) 0)
#:unless (>= (+ (cdr delta) y) (vector-length grid))
#:unless (< (+ (cdr delta) y) 0))
(match (input-ref grid (+ (cdr delta) y) (+ (car delta) x))
[(or #\. #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #f]
[_ #t])))
(for/sum ([line (in-vector input)] [y (in-naturals)])
(for/sum ([posn (in-list (regexp-match-positions* #px"[0-9]+" line))]
#:do [(define xmin (car posn)) (define xmax (cdr posn))])
(if (for/or ([x (in-range xmin xmax)]) (symbol-adjacent? input y x))
(string->number (substring line xmin xmax))
0))))
(define (part2 input)
(define (input-ref grid y x)
(string-ref (vector-ref grid y) x))
(define (find-adj-numbers grid y x)
(for/list ([delta (in-list '((0 . 1) (1 . 1) (1 . 0)
(1 . -1) (0 . -1) (-1 . -1)
(-1 . 0) (-1 . 1)))]
#:unless (>= (+ (car delta) x) (string-length (vector-ref grid y)))
#:unless (< (+ (car delta) x) 0)
#:unless (>= (+ (cdr delta) y) (vector-length grid))
#:unless (< (+ (cdr delta) y) 0)
#:when (member (input-ref grid (+ (cdr delta) y) (+ (car delta) x))
'(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)))
(cons (+ (car delta) x) (+ (cdr delta) y))))
(define nums (make-hash))
(for ([line (in-vector input)] [y (in-naturals)])
(for ([posn (in-list (regexp-match-positions* #px"[0-9]+" line))]
#:do [(define xmin (car posn)) (define xmax (cdr posn))])
(for ([x (in-range xmin xmax)])
(hash-set! nums (cons x y) (list xmin y (string->number (substring line xmin xmax)))))))
(for/sum ([line (in-vector input)] [y (in-naturals)])
(for/sum ([chr (in-list (string->list line))] [x (in-naturals)]
#:when (equal? chr #\*))
(define adj-nums (find-adj-numbers input y x))
(define adj-num-entries
(for/set ([a-n (in-list adj-nums)])
(hash-ref nums a-n)))
(if (= 2 (set-count adj-num-entries))
(apply * (map #{third %} (set->list adj-num-entries)))
0))))
(define (parse fname)
(list->vector (file->lines fname)))
(module+ main
(define input (parse "inputs/3"))
(answer 3 1 (time (part1 input)))
(answer 3 2 (time (part2 input)))
(displayln "meow"))