-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday7.rkt
70 lines (60 loc) · 2.84 KB
/
day7.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
62
63
64
65
66
67
68
69
70
#lang racket
(require point-free rackunit "utils.rkt")
(provide part1 part2 tests)
(define input (file->lines "input/d7"))
; TODO refactor
(define (part1)
(count identity (map (compose (curry has-descendant? "shiny gold")
first
parse-line)
input)))
(define (part2) (count-descendants "shiny gold"))
(define (parse-line line)
(match (regexp-match #px"(\\w+ \\w+) bags contain (.*)" line)
[(list _ parent "no other bags.") (list parent '())]
[(list _ parent rest)
(list parent (map (match-lambda [(list n c)
(cons (string->number n) c)])
(regexp-match* #px"(\\d+) (\\w+ \\w+) bags*"
rest
#:match-select cdr)))]))
(define bag-hash
(foldl (match-lambda** [((list k v) h) (hash-set h k v)])
(hash)
(map parse-line input)))
(define (has-descendant? bag-to-find bag)
(let ([xs (map cdr (hash-ref bag-hash bag))])
(or (list-member? bag-to-find xs)
(ormap (curry has-descendant? bag-to-find) xs))))
(define/compose count-descendants
(curry apply +)
(curry map (match-lambda [(cons n c)
(* n (+ 1 (count-descendants c)))]))
(curry hash-ref bag-hash))
(define-test-suite
tests
(test-case "parses a line into a bag along with the bags it contains"
(check-equal?
(parse-line (string-append "light red bags contain "
"4 shiny bronze bags, "
"2 mirrored gray bags, "
"5 dark violet bags."))
'("light red" ((4 . "shiny bronze")
(2 . "mirrored gray")
(5 . "dark violet"))))
(check-equal?
(parse-line (string-append "bright white bags contain "
"1 posh gold bag, "
"5 mirrored silver bags."))
'("bright white" ((1 . "posh gold")
(5 . "mirrored silver"))))
(check-equal?
(parse-line (string-append "striped magenta bags contain "
"2 drab olive bags, "
"3 dim chartreuse bags, "
"3 plaid beige bags, "
"5 mirrored crimson bags."))
'("striped magenta" ((2 . "drab olive")
(3 . "dim chartreuse")
(3 . "plaid beige")
(5 . "mirrored crimson"))))))