-
Notifications
You must be signed in to change notification settings - Fork 0
/
day07.clj
66 lines (53 loc) · 1.76 KB
/
day07.clj
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
(ns advent.day07
(:require [advent.util :refer [get-resource split-groups]]
[clojure.set :refer [union intersection]]
[clojure.string :as string]))
(def test1-data (string/split-lines (get-resource "test1")))
(def test2-data (string/split-lines (get-resource "test2")))
(def real-data (string/split-lines (get-resource "real")))
;; Part 1
(defn parse-line-v1 [line]
(let [[mpar & mch] (re-seq #"(\w+ \w+) bag" line)]
[(second mpar) (map second mch)]))
(defn ancestors [tbl c]
(let [ps (tbl c)]
(if (empty? ps)
[]
(distinct (apply concat ps (map (partial ancestors tbl) ps))))))
(defn answer1 [data color]
(let [flip (fn [[p c]] (mapv #(vec [% p]) c))
tbl (->> data
(mapv parse-line-v1)
(mapv flip)
(apply concat)
(reduce (fn [acc [k v]] (update acc k conj v)) {}))
]
(count (ancestors tbl color))
))
(assert (= 4 (answer1 test1-data "shiny gold")))
(comment
; Answer 1
(answer1 real-data "shiny gold"))
;; Part 2
(defn parse-line-v2 [line]
(let [mpar (re-find #"(\w+ \w+) bags contain" line)
mch (re-seq #"(\d+) (\w+ \w+) bag" line)]
[(second mpar) (map #(vec [(Integer/parseInt (second %)) (nth % 2)]) mch)]
))
(defn count-children [tbl [n c]]
(let [cs (tbl c)]
(if (empty? cs)
n
(+ n (* n (apply + (map (partial count-children tbl) cs))))
)))
(defn answer2 [data color]
(let [tbl (->> data
(mapv parse-line-v2)
(apply concat)
(apply hash-map))]
(dec (count-children tbl [1 color]))))
(assert (= 32 (answer2 test1-data "shiny gold")))
(assert (= 126 (answer2 test2-data "shiny gold")))
(comment
; Answer 2
(answer2 real-data "shiny gold"))