ref: 3703478dcfedd048437f7a0515dbda2ff8a22d8d
src/aoc/day02.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 |
(ns aoc.day02 (:require [clojure.java.io :as io])) (def example "1-3 a: abcde 1-3 b: cdefg 2-9 c: ccccccccc") ;; https://gist.github.com/edbond/665401 (defmacro xor "Evaluates exprs one at a time, from left to right. If only one form returns a logical true value (neither nil nor false), returns true. If more than one value returns logical true or no value returns logical true, retuns a logical false value. As soon as two logically true forms are encountered, no remaining expression is evaluated. (xor) returns nil." ([] nil) ([f & r] `(loop [t# false f# '[~f ~@r]] (if-not (seq f#) t# (let [fv# (eval (first f#))] (cond (and t# fv#) false (and (not t#) fv#) (recur true (rest f#)) :else (recur t# (rest f#)))))))) (defn parse-line [line] (zipmap [:min :max :letter :password] (rest (re-find #"(\d+)-(\d+) (\w): (\w+)" line)))) (defn string-to-char [s] (first (char-array s))) (defn password-valid? [p] (let [min (read-string (:min p)) max (read-string (:max p)) freqs (frequencies (:password p)) letter (string-to-char (:letter p)) letter-count (get freqs letter 0)] (and (>= letter-count min) (<= letter-count max)))) (defn password-valid-2? [p] (let [pass (:password p) idx-1 (get pass (dec (read-string (:min p)))) idx-2 (get pass (dec (read-string (:max p)))) letter (string-to-char (:letter p))] (xor (= idx-1 letter) (= idx-2 letter)))) (defn check-passwords [acc val] (if (password-valid? val) (inc acc) acc)) (defn check-passwords-2 [acc val] (if (password-valid-2? val) (inc acc) acc)) ;; ---- (defn read-input [] (->> (io/resource "input02.txt") slurp clojure.string/split-lines (map parse-line))) (defn compute-1 [input] (reduce check-passwords 0 input)) (defn compute-2 [input] (reduce check-passwords-2 0 input)) (defn main [] (let [input (read-input)] (println (compute-1 input)) (println (compute-2 input)))) (main) |