ref: master
2020/src/aoc/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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
(ns aoc.day07 (:require [clojure.java.io :as io])) (def example "light red bags contain 1 bright white bag, 2 muted yellow bags. dark orange bags contain 3 bright white bags, 4 muted yellow bags. bright white bags contain 1 shiny gold bag. muted yellow bags contain 2 shiny gold bags, 9 faded blue bags. shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags. dark olive bags contain 3 faded blue bags, 4 dotted black bags. vibrant plum bags contain 5 faded blue bags, 6 dotted black bags. faded blue bags contain no other bags. dotted black bags contain no other bags.") (def rule-pattern #"(\d+) (\w+ \w+)") (def mine "shiny gold") (defn parse-sub [s] (let [[_ number color] (re-find rule-pattern s)] {:color color :number (read-string number)})) (defn parse-contents [s] (when-not (clojure.string/starts-with? s "no") (let [rules (clojure.string/split s #", ")] (map parse-sub rules)))) (defn parse-rule [s] (let [[bag contents] (clojure.string/split s #" contain ") [shade color _] (clojure.string/split bag #" ") contents (parse-contents contents)] {:color (str shade " " color) :contents contents})) (defn graph [rules] (reduce (fn [acc {:keys [color contents]}] (reduce (fn [acc content] (update acc (:color content) conj {:color color :number (:number content)})) acc contents)) {} rules)) (defn graph2 [rules] (reduce (fn [acc {:keys [color contents]}] (reduce (fn [acc2 content] (update acc2 color conj content)) acc contents)) {} rules)) (defn get-parents [graph color] (get graph color)) (defn fold [g] (loop [r (into #{} (->> (get-parents g mine) (map :color)))] (let [r2 (reduce (fn [acc color] (into acc (->> (get-parents g color) (map :color)))) r r)] (if (= r r2) r (recur r2))))) (defn count-contents [g c] (let [contents (get-parents g c)] (if (seq contents) (reduce (fn [acc {:keys [color number]}] (+ acc (* number (count-contents g color)))) 1 contents) 1))) ;; --- (defn read-input [] (->> (slurp (io/resource "input07.txt")) (clojure.string/split-lines))) (defn compute-1 [input] (let [rules (map parse-rule input) g (graph rules)] (count (fold g)))) (defn compute-2 [input] (let [rules (map parse-rule input) g (graph2 rules)] (dec (count-contents g mine)))) (defn main [] (let [input (read-input)] (println (compute-1 input)) (println (compute-2 input)))) (main) |