ref: 3703478dcfedd048437f7a0515dbda2ff8a22d8d
src/aoc/day04.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 |
(ns aoc.day04 (:require [clojure.java.io :as io])) (def fields #{:byr :iyr :eyr :hgt :hcl :ecl :pid :cid}) (def height-pattern #"(\d+)(cm|in)") (def hcolor-pattern #"#[a-f0-9]{6}") (def eye-color-set #{"amb" "blu" "brn" "gry" "grn" "hzl" "oth"}) (def pid-pattern #"\d{9}") (def validation {:byr (fn [v] (when (= 4 (count v)) (let [n (read-string v)] (<= 1920 n 2002)))) :iyr (fn [v] (when (= 4 (count v)) (let [n (read-string v)] (<= 2010 n 2020)))) :eyr (fn [v] (when (= 4 (count v)) (let [n (read-string v)] (<= 2020 n 2030)))) :hgt (fn [v] (when-let [[_ digits u] (re-find height-pattern v)] (let [n (read-string digits)] (case u "cm" (<= 150 n 193) "in" (<= 59 n 76))))) :hcl (fn [v] (re-matches hcolor-pattern v)) :ecl (fn [v] (contains? eye-color-set v)) :pid (fn [v] (re-matches pid-pattern v)) :cid (fn [v] true)}) (def optional-fields (set [:cid])) (def required-fields (clojure.set/difference fields optional-fields)) (defn collect-pair [acc p] (let [[k v] (clojure.string/split p #":")] (assoc acc (keyword k )v))) (defn parse-passport [s] (let [lines (clojure.string/split-lines s) joined (clojure.string/join " " lines) pairs (clojure.string/split joined #" ")] (reduce collect-pair {} pairs))) (defn valid? [p] (let [pfields (set (keys p))] (= (clojure.set/intersection required-fields pfields) required-fields))) (defn valid-2? [p] (when (valid? p) (let [ok (map (fn [field] (let [f (get validation field (constantly true)) v (get p field)] (f v))) required-fields)] (every? identity ok)))) ;; ----------------------------------------------------------------------------- (defn read-input [] (->> (clojure.string/split (slurp (io/resource "input04.txt")) #"\n\n") (map parse-passport))) (defn compute-1 [input] (count (filter valid? input))) (defn compute-2 [input] (count (filter valid-2? input))) (defn main [] (let [input (read-input)] (println (compute-1 input)) (println (compute-2 input)))) (main) |