X-Git-Url: http://git.jkinsey.net/?a=blobdiff_plain;f=src%2Fadventofcode2019%2Fday07.clj;fp=src%2Fadventofcode2019%2Fday07.clj;h=9b43cc4987229cae78afd7375fb7ad3006458b8c;hb=d0f13cd27088cf370a59e78e8438bef9bbddb13e;hp=0000000000000000000000000000000000000000;hpb=2bdba7155e96f282678e2721cc744d823d7eebf9;p=adventofcode2019.git diff --git a/src/adventofcode2019/day07.clj b/src/adventofcode2019/day07.clj new file mode 100644 index 0000000..9b43cc4 --- /dev/null +++ b/src/adventofcode2019/day07.clj @@ -0,0 +1,85 @@ +(ns adventofcode2019.day07 + [:require [adventofcode2019.lib :refer :all] + [clojure.string :as str] + [clojure.math.combinatorics :as combo]]) + +;; a slightly less awful hack +(def phase-setting (atom [nil 0 nil nil nil nil + nil nil nil nil nil nil])) +(defn get-phase-setting [] + (let [input (first @phase-setting)] + (swap! phase-setting subvec 1) + input)) +(defn put-phase-setting [input] + (swap! phase-setting assoc 1 input)) + +;; 0: function args&mem -> [mem (ctr -> ctr)] +;; 1: number of args +(def operations {1 [(fn [a b c mem] + [(assoc mem c (+ a b)) #(+ % 4)]) + 3] + 2 [(fn [a b c mem] + [(assoc mem c (* a b)) #(+ % 4)]) + 3] + 3 [(fn [a mem] + [(assoc mem a (get-phase-setting)) #(+ % 2)]) + 1] + 4 [(fn [a mem] + (put-phase-setting (mem a)) + [mem #(+ % 2)]) + 1] + 5 [(fn [a b mem] + [mem (if (not= a 0) (constantly b) #(+ % 3))]) + 2] + 6 [(fn [a b mem] + [mem (if (= a 0) (constantly b) #(+ % 3))]) + 2] + 7 [(fn [a b c mem] + [(assoc mem c (if (< a b) 1 0)) #(+ % 4)]) + 3] + 8 [(fn [a b c mem] + [(assoc mem c (if (= a b) 1 0)) #(+ % 4)]) + 3]}) + +;; FIXME: sorry about the dropped forms i didn't want to fix it properly +;; the problem is that flags don't apply to certain args for certain ops +(defn decode-op [opcode] + (let [str-code (format "%05d" opcode) + [f3 f2 f1] (map #(= \1 %) (take 3 str-code)) + op (parse-int (str/join (drop 3 str-code))) + [operation arg-ct] (operations op)] + [(case arg-ct + 1 #(operation #_((if f1 identity %1) %2) %2 %1) + 2 #(operation ((if f1 identity %1) %2) + ((if f2 identity %1) %3) %1) + 3 #(operation ((if f1 identity %1) %2) + ((if f2 identity %1) %3) + #_((if f3 identity %1) %4) %4 %1)) + arg-ct])) + +(defn perform-operation [program counter] + (let [opcode (program counter) + [operation arg-ct] (decode-op opcode) + args (->> (iterate inc counter) + (rest) + (take arg-ct) + (map program))] + (let [[program ctr-update] (apply operation program args)] + [program (ctr-update counter)]))) + +(defn intcode [program] + (loop [[program counter] [program 0]] + (let [opcode (program counter)] + (if (= opcode 99) + program + (recur (perform-operation program counter)))))) + +(defn day07 [] + (let [input (mapv parse-int (get-list-from-file (input-file) #",")) + phase-settings (combo/permutations [0 1 2 3 4]) + all-outputs (for [[a b c d e] phase-settings] + (do (reset! phase-setting [a 0 b nil c nil d nil e nil nil nil]) + (dotimes [_ 5] (intcode input)) + (last @phase-setting)))] + (part1 (apply max all-outputs)) + #_(part2 )))