diff options
Diffstat (limited to '03')
| -rw-r--r-- | 03/1.rkt | 84 | ||||
| -rw-r--r-- | 03/2.rkt | 102 |
2 files changed, 186 insertions, 0 deletions
diff --git a/03/1.rkt b/03/1.rkt new file mode 100644 index 0000000..55a4281 --- /dev/null +++ b/03/1.rkt @@ -0,0 +1,84 @@ +#lang racket + +(require "../lib/utils.rkt") +(require "../lib/obj.rkt") + +(define (read-input) + (call-with-input-file "input" + (λ (fp) + (list->vector (get-lines fp))))) + +(define schema (read-input)) + +(define (char-at line col) + (string-ref (vector-ref schema line) col)) + +(define height (vector-length schema)) +(define width (string-length (vector-ref schema 0))) + +(define make-num (obj-maker 'line 'col 'value 'length)) + +(define (scan-nums) + (define nums '()) + (let loop ((i 0)) + (if (>= i height) + (void) + (let () + (let loop ((j 0)) + (define curline (vector-ref schema i)) + (if (>= j width) + (void) + (let () + (define next 1) + (define (find-next) + (if (or (>= (+ j next) 140) + (not (char-numeric? (char-at i (+ j next))))) + (void) + (let () + (set! next (+ 1 next)) + (find-next)))) + (if (char-numeric? (char-at i j)) + (let () + (find-next) + (define value (string->number (substring curline j (+ j next)))) + (set! nums (cons (make-num i j value next) nums))) + (void)) + (loop (+ j next))))) + (loop (+ 1 i))))) + (reverse nums)) +(define nums (scan-nums)) + +(define (is-symbol? c) + (and (not (char-numeric? c)) + (not (char=? #\. c)))) + +(define (collect-adjacent num) + (define left + (if (= 0 (num 'col)) + '() + (list (char-at (num 'line) (- (num 'col) 1))))) + (define right + (if (= width (+ (num 'col) (num 'length))) + '() + (list (char-at (num 'line) (+ (num 'col) (num 'length)))))) + (define up + (if (= 0 (num 'line)) + '() + (string->list + (substring (vector-ref schema (- (num 'line) 1)) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1)))))) + (define down + (if (= (- height 1) (num 'line)) + '() + (string->list + (substring (vector-ref schema (+ (num 'line) 1)) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1)))))) + (append left right up down)) + +(define (is-part-num? num) + (findf is-symbol? (collect-adjacent num))) + +(apply + (map (λ (x) (x 'value)) + (filter is-part-num? nums)))
\ No newline at end of file diff --git a/03/2.rkt b/03/2.rkt new file mode 100644 index 0000000..238ed2c --- /dev/null +++ b/03/2.rkt @@ -0,0 +1,102 @@ +#lang racket + +(require "../lib/utils.rkt") +(require "../lib/obj.rkt") + +(define (read-input) + (call-with-input-file "input" + (λ (fp) + (list->vector (get-lines fp))))) + +(define schema (read-input)) + +(define (char-at line col) + (string-ref (vector-ref schema line) col)) + +(define height (vector-length schema)) +(define width (string-length (vector-ref schema 0))) + +(define make-num (obj-maker 'line 'col 'value 'length)) + +(define (scan-nums) + (define nums '()) + (let loop ((i 0)) + (if (>= i height) + (void) + (let () + (let loop ((j 0)) + (define curline (vector-ref schema i)) + (if (>= j width) + (void) + (let () + (define next 1) + (define (find-next) + (if (or (>= (+ j next) 140) + (not (char-numeric? (char-at i (+ j next))))) + (void) + (let () + (set! next (+ 1 next)) + (find-next)))) + (if (char-numeric? (char-at i j)) + (let () + (find-next) + (define value (string->number (substring curline j (+ j next)))) + (set! nums (cons (make-num i j value next) nums))) + (void)) + (loop (+ j next))))) + (loop (+ 1 i))))) + (reverse nums)) +(define nums (scan-nums)) + +(define (collect-adjacent-positions num) + (define (position-range line start end) + (define delta (- end start)) + (map list (repeat delta line) (range start end))) + (define left + (if (= 0 (num 'col)) + '() + (list (list (num 'line) (- (num 'col) 1))))) + (define right + (if (= width (+ (num 'col) (num 'length))) + '() + (list (list (num 'line) (+ (num 'col) (num 'length)))))) + (define up + (if (= 0 (num 'line)) + '() + (position-range (- (num 'line) 1) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1))))) + (define down + (if (= (- height 1) (num 'line)) + '() + (position-range (+ (num 'line) 1) + (max 0 (- (num 'col) 1)) + (min width (+ (num 'col) (num 'length) 1))))) + (append left right up down)) + +(define asterisks (make-hash)) + +(define (mark-adj-asterisk num) + (define adjs (collect-adjacent-positions num)) + (define (mark coord) + (if (not (char=? #\* (char-at (car coord) (cadr coord)))) + (void) + (let () + (when (not (hash-has-key? asterisks coord)) + (hash-set! asterisks coord '())) + (hash-set! asterisks coord (cons (num 'value) (hash-ref asterisks coord)))))) + (for-each mark adjs)) + +(for-each mark-adj-asterisk nums) + +(define aster-list (hash->list asterisks)) + +(define (is-gear? aster) + (define nums-list (cdr aster)) + (= 2 (length nums-list))) + +(define (power aster) + (define nums-list (cdr aster)) + (* (car nums-list) (cadr nums-list))) + +(apply + (map power (filter is-gear? aster-list))) |
