-
Notifications
You must be signed in to change notification settings - Fork 1
/
day10.rkt
61 lines (54 loc) · 1.96 KB
/
day10.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#lang racket/base
(require racket/file
racket/list
racket/match)
(define (corrupted-score c)
(match c
[#\) 3]
[#\] 57]
[#\} 1197]
[#\> 25137]))
(define (read-chunk in)
(let/ec return
(let read-loop ()
(define (read-pair open close)
(let loop ([children null])
(define c (peek-char in))
(cond
[(eof-object? c) (list open (reverse children) 'eof)]
[(equal? c close) (list open (reverse children) (read-char in))]
[(member c '(#\) #\] #\} #\>)) (return (corrupted-score (read-char in)))]
[else (loop (cons (read-loop) children))])))
(match (read-char in)
[(? eof-object?) 'eof]
[#\( (read-pair #\( #\))]
[#\[ (read-pair #\[ #\])]
[#\{ (read-pair #\{ #\})]
[#\< (read-pair #\< #\>)]))))
(define lines (file->lines "day10.txt"))
(define part1
(for/sum ([line (in-list lines)])
(define maybe-score (read-chunk (open-input-string line)))
(if (number? maybe-score) maybe-score 0)))
(define (incomplete-score c)
(match c
[`(,c ,children eof)
(define score (add1 (index-of '(#\( #\[ #\{ #\<) c)))
(+ score (* 5 (apply + (filter-map incomplete-score children))))]
[_ #f]))
(define part2
(let* ([scores (for*/list ([line (in-list lines)]
[line-in (in-value (open-input-string line))]
[chunk-or-score (in-value (read-chunk line-in))]
#:unless (number? chunk-or-score))
(define chunk
(let loop ([prev chunk-or-score])
(define curr (read-chunk line-in))
(if (eq? curr 'eof) prev (loop curr))))
(incomplete-score chunk))]
[scores (sort (filter values scores) <)])
(list-ref scores (quotient (length scores) 2))))
(module+ test
(require rackunit)
(check-= part1 370407 0)
(check-= part2 3249889609 0))