(defn parse-bag-rule [s] (let [[_ bag contents] (re-matches #"^(.*?) bags contain (.*)$" s) bags (re-seq #"(\d+) (\w+ \w+)" contents)] [bag (into {} (map (fn [[_ n tag]] [tag (clojure.edn/read-string n)]) bags))])) (def bags (into {} (map parse-bag-rule (clojure.string/split-lines input-7)))) ;; part 1 (->> bags keys (filter #(->> (tree-seq (constantly true) (comp keys bags) %) rest (some #{"shiny gold"}))) count) ;; part 2 (->> ["shiny gold" 1] (tree-seq (constantly true) (fn [[tag amount]] (map #(update % 1 * amount) (bags tag)))) (map second) (apply +) dec)