Skip to content

Commit 38f8593

Browse files
committed
add day 3
1 parent f49c572 commit 38f8593

File tree

4 files changed

+237
-7
lines changed

4 files changed

+237
-7
lines changed

day02.rkt

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
(for/hasheq ([reveal-str (in-list (string-split set-str ","))])
1111
(match-define (regexp #rx"([0-9]+) ([a-z]+)"
1212
(list _
13-
(app string->number n)
13+
(app string->number blocks)
1414
(app string->symbol color)))
1515
reveal-str)
16-
(values color n)))
16+
(values color blocks)))
1717

1818
(define (parse-game line)
1919
(match-define (regexp #rx"Game ([^:]+): (.+)"
@@ -34,11 +34,10 @@
3434
(<= (hash-ref s 'blue 0) 14)))
3535

3636
(define (game-minimums g)
37-
(for/fold ([minimums (hasheq 'red 0 'green 0 'blue 0)])
38-
([s (in-list (game-sets g))])
39-
(for/fold ([minimums minimums])
40-
([color (in-list '(red green blue))])
41-
(hash-update minimums color (λ (n) (max n (hash-ref s color 0)))))))
37+
(for*/fold ([minimums (hasheq 'red 0 'green 0 'blue 0)])
38+
([s (in-list (game-sets g))]
39+
[c (in-list '(red green blue))])
40+
(hash-update minimums c (λ (blocks) (max blocks (hash-ref s c 0))))))
4241

4342
(define (game-power g)
4443
(apply * (hash-values (game-minimums g))))

day03-example.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
467..114..
2+
...*......
3+
..35..633.
4+
......#...
5+
617*......
6+
.....+.58.
7+
..592.....
8+
......755.
9+
...$.*....
10+
.664.598..

day03.rkt

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#lang racket/base
2+
3+
(define table
4+
(call-with-input-file "day03.txt"
5+
(lambda (in)
6+
(for*/vector ([line (in-lines in)]
7+
[char (in-string line)])
8+
char))))
9+
(define s (sqrt (vector-length table)))
10+
(define -s (- s))
11+
12+
(define (engine-symbol? c)
13+
(and (not (eqv? c #\.))
14+
(not (char-numeric? c))))
15+
16+
(define-syntax-rule (define-finder id for*-id)
17+
(define (id t pos [ok? engine-symbol?])
18+
(for*-id ([d (in-list (list (- -s 1) -s (+ -s 1)
19+
-1 1
20+
(- s 1) s (+ s 1)))]
21+
[idx (in-value (+ pos d))]
22+
#:when (and (>= idx 0)
23+
(< idx (vector-length t))
24+
(ok? (vector-ref t idx))))
25+
idx)))
26+
27+
(define-finder find-adjacent for*/list)
28+
(define-finder has-adjacent? for*/first)
29+
30+
(define (char->decimal c)
31+
(- (char->integer c)
32+
(char->integer #\0)))
33+
34+
(define part1
35+
(for/fold ([num 0]
36+
[ok? #f]
37+
[total 0]
38+
#:result (if ok? (+ num total) total))
39+
([(c idx) (in-indexed (in-vector table))])
40+
(if (char-numeric? c)
41+
(values (+ (* num 10) (char->decimal c))
42+
(or ok? (has-adjacent? table idx))
43+
total)
44+
(values 0 #f (if ok? (+ num total) total)))))
45+
46+
(module+ test
47+
(require rackunit)
48+
(check-equal? part1 528799))
49+
50+
; invariant: indexes always start out as valid digit positions in the table
51+
(define (get-numbers t is)
52+
(let loop ([is is]
53+
[nums null])
54+
(cond
55+
[(null? is) nums]
56+
[else
57+
(define-values (num rem-is)
58+
(let get-number ([i (car is)])
59+
(if (or (< i 0)
60+
(not (char-numeric? (vector-ref t i))))
61+
(for/fold ([n 0] [rem-is is])
62+
([(c idx) (in-indexed (in-vector t (add1 i)))])
63+
#:break (not (char-numeric? c))
64+
(values
65+
(+ (* n 10) (char->decimal c))
66+
(remq (+ (add1 i) idx) rem-is)))
67+
(get-number (sub1 i)))))
68+
(loop rem-is (cons num nums))])))
69+
70+
(define part2
71+
(for/fold ([total 0])
72+
([(c idx) (in-indexed (in-vector table))]
73+
#:when (eqv? c #\*))
74+
(define adjacent-numbers
75+
(get-numbers table (find-adjacent table idx char-numeric?)))
76+
(if (= (length adjacent-numbers) 2)
77+
(+ total (apply * adjacent-numbers))
78+
total)))
79+
80+
(module+ test
81+
(check-equal? part2 84907174))

0 commit comments

Comments
 (0)