(require '[clojure.string :as str]) (require '[clojure.set :as set]) (defn find-match " Searches for digit that `has segs-left` segments remaining after the segments of `dig-to-cmp` are removed from the digits in `cnts` with `grp-to-cmp` segments. " [segs-left dig-to-cmp cnts grp-to-cmp] (as-> cnts $ (filterv #(= (first %) grp-to-cmp) $) (filterv #(-> (second %) (str/replace (re-pattern (str/join ["[" dig-to-cmp "]"])) "") (count) (= segs-left) ) $ ) (get-in $ [0 1]) ) ) (defn determine-digits [line] (let [counts (mapv #(do [(count %) %]) (take 10 line)) mcounts (into {} counts)] (as-> {} $ (assoc $ 1 (mcounts 2) 4 (mcounts 4) 7 (mcounts 3) 8 (mcounts 7) ) (assoc $ 3 (find-match 2 ($ 7) counts 5) 6 (find-match 4 ($ 7) counts 6) 2 (find-match 3 ($ 4) counts 5) 9 (find-match 2 ($ 4) counts 6) ) (assoc $ 5 (find-match 2 ($ 2) counts 5)) (assoc $ 0 (find-match 2 ($ 5) counts 6)) ) ) ) (println (reduce (fn [sum input] (let [line (as-> input $ (str/split $ #" ") (mapv (comp str/join sort) $) ) number (subvec line 11 15) decoder (set/map-invert (determine-digits line))] (->> number (map (comp str decoder)) (str/join) (#(Integer/parseInt %)) (+ sum) ) ) ) 0 (str/split-lines (slurp "./in")) ) )