(ns question-3 (:require [inputs])) (def mock-input "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))") (def mock-input-2 "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))") (defn get-instructions [input] (->> input (re-seq #"(don't\(\))|(do\(\))|(mul\(\d{0,3},\d{0,3}\))") (map first))) (defn parse-mul-instruction [mul-instruction] (let [re #"\w+\((\w+),\s*(\w+)\)" groups (re-matches re mul-instruction)] (map parse-long (rest groups)))) (defn process-in-do [xf] (let [prev (volatile! true)] (fn ([] (xf)) ([result] (xf result)) ([result input] (let [in-do? @prev] (case input "do()" (vreset! prev true) "don't()" (vreset! prev false) (when in-do? (xf result input)))))))) (defn question-3-a [input] (let [instructions (get-instructions input) xf (comp (map parse-mul-instruction) (filter seq?) (map #(apply * %)))] (transduce xf + 0 instructions))) (defn question-3-b [input] (let [instructions (get-instructions input) xf (comp process-in-do (map parse-mul-instruction) (map #(apply * %))) products (sequence xf instructions)] ;; for some reason the transduce function throws an exception (reduce + 0 products))) (defn -main [] (println "Solution to question 3-a is: " (question-3-a inputs/question-3)) (println "Solution to question 3-b is: " (question-3-b inputs/question-3)))