(ns question-5 (:require [clojure.string :as strings] [inputs])) (def mock-input "47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47") (defn parse-rule [str-rule] (mapv parse-long (strings/split str-rule #"\|"))) (defn parse-rules [str-rules] (mapv parse-rule str-rules)) (defn get-raw-rules [input] (-> input (strings/split #"\n\n") first (strings/split-lines) parse-rules)) (defn index-of [vec itm] (.indexOf vec itm)) (defn create-rule [[low high]] (fn [xmas-update] (let [low-idx (index-of xmas-update low) high-idx (index-of xmas-update high)] (or (= low-idx -1) (= high-idx -1) (< low-idx high-idx))))) (defn rules-from-raw-rules [raw-rules] (let [rules (map create-rule raw-rules)] (fn [xmas-update] (every? #(% xmas-update) rules)))) (defn get-rules [input] (rules-from-raw-rules (get-raw-rules input))) (defn get-xmas-updates [input] (let [parse-xmas-input #(mapv parse-long (strings/split % #"\,")) parse-xmas-inputs #(map parse-xmas-input %)] (-> input (strings/split #"\n\n") second (strings/split-lines) parse-xmas-inputs))) (defn get-middle [v] (get v (/ (-> v count dec) 2))) (defn question-5-a [input] (let [rules (get-rules input) xmas-updates (get-xmas-updates input) xf (comp (filter rules) (map get-middle))] (transduce xf + 0 xmas-updates))) (defn fix-xmas-update-for-rule [xmas-update [low high]] (let [low-idx (index-of xmas-update low) high-idx (index-of xmas-update high)] (if (and (not= high-idx -1) (not= low-idx -1) (< high-idx low-idx)) (-> xmas-update (assoc low-idx high) (assoc high-idx low)) xmas-update))) (defn do-fix-xmas-update [xmas-update raw-rules] (if (empty? raw-rules) xmas-update (recur (fix-xmas-update-for-rule xmas-update (first raw-rules)) (rest raw-rules)))) (defn fix-xmas-update [xmas-update raw-rules] (let [ret (do-fix-xmas-update xmas-update raw-rules)] (if ((rules-from-raw-rules raw-rules) ret) ret (recur ret raw-rules)))) (defn question-5-b [input] (let [rules (get-rules input) raw-rules (get-raw-rules input) xmas-updates (get-xmas-updates input) xf (comp (remove rules) (map #(fix-xmas-update % raw-rules)) (map get-middle))] (transduce xf + 0 xmas-updates))) (defn -main [] (println "Solution to question 5-a is: " (question-5-a inputs/question-5)) (println "Solution to question 5-b is: " (question-5-b inputs/question-5)))