aboutsummaryrefslogtreecommitdiff
path: root/03
diff options
context:
space:
mode:
Diffstat (limited to '03')
-rw-r--r--03/1.rkt84
-rw-r--r--03/2.rkt102
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)))