diff --git a/src/day04.clj b/src/day04.clj index d5e05a6..509da85 100644 --- a/src/day04.clj +++ b/src/day04.clj @@ -8,23 +8,48 @@ (defn parse-line [l] (let [m (rest (re-find #"Card +(\d+): +([\d ]+) \| +([\d ]+)" l))] - [(read-string (first m)) (mapv parse-numbers (rest m))])) + [(read-string (first m)) + (assoc + (zipmap [:winning :had] (mapv parse-numbers (rest m))) + :copies 0)])) (def input (->> "inputs/day04" slurp string/split-lines (mapcat parse-line) - (apply hash-map))) + (apply sorted-map))) -(defn count-winning [[_ [winning had]]] +(defn count-winning [{:keys [winning had]}] (->> (map #(some #{%} winning) had) (remove nil?) count)) (def part1-answer - (->> (map count-winning input) + (->> (vals input) + (map count-winning) (map #(case % 0 0 1 1 (pow 2 (dec %)))) (reduce +))) + +(def part2-answer + (->> + (loop [cards input + todo input] + (if (empty? todo) + cards + (let [current (first todo) + current-id (key current) + current-copies (inc (:copies (val current))) + matching (count-winning (val current)) + to-win (range (inc current-id) + (inc (+ current-id matching))) + cards' (reduce + (fn [cards i] + (update-in cards [i :copies] (partial + current-copies))) + cards + to-win)] + (recur cards' (drop current-id cards'))))) + (map #(inc (get (val %) :copies))) + (reduce +)))