diff options
Diffstat (limited to 'year2021/day24/partboth.clj')
-rw-r--r-- | year2021/day24/partboth.clj | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/year2021/day24/partboth.clj b/year2021/day24/partboth.clj new file mode 100644 index 0000000..9548ec3 --- /dev/null +++ b/year2021/day24/partboth.clj @@ -0,0 +1,41 @@ +(require '[clojure.string :as str]) + +; The given program operates on a base-26 stack, either pushing or +; (conditionally) popping values. This code extracts those operations +; from the input, then works through them to determine the highest +; and lowest values that produce an output of zero. +; See the .md file in this directory for more info. + +(def program (->> (slurp "./in") + str/split-lines + (map #(str/split % #"\s+")) + (partition 18) + (map (fn [step] + (if (= "1" (last (nth step 4))) + [:push (read-string (last (nth step 15)))] + [:pop (read-string (last (nth step 5)))]) + )))) + +(defn program-index [prog] (- 14 (count prog))) + +(loop [numbers (vec (repeat 2 (vec (repeat 14 0)))) + stack '() + prog program] + (if-let [step (first prog)] + (if (= :push (first step)) + (recur numbers + (conj stack [(program-index prog) (second step)]) + (rest prog)) + (let [i2 (program-index prog) + [i1 v] (first stack) + diff (+ v (second step))] + (recur + [(if (neg? diff) + (-> (first numbers) (assoc i1 9) (assoc i2 (+ 9 diff))) + (-> (first numbers) (assoc i2 9) (assoc i1 (- 9 diff)))) + (if (neg? diff) + (-> (second numbers) (assoc i2 1) (assoc i1 (- 1 diff))) + (-> (second numbers) (assoc i1 1) (assoc i2 (+ 1 diff))))] + (rest stack) (rest prog)))) + (println (map str/join numbers)))) + |