X-Git-Url: http://git.jkinsey.net/?a=blobdiff_plain;f=src%2Fadventofcode2019%2Fday07.clj;fp=src%2Fadventofcode2019%2Fday07.clj;h=d2617f72d3e4cf3013c3db9c8d45f5359d46b6df;hb=9a22e14c7830c284c4d6f8fa402734908a128458;hp=9b43cc4987229cae78afd7375fb7ad3006458b8c;hpb=d0f13cd27088cf370a59e78e8438bef9bbddb13e;p=adventofcode2019.git diff --git a/src/adventofcode2019/day07.clj b/src/adventofcode2019/day07.clj index 9b43cc4..d2617f7 100644 --- a/src/adventofcode2019/day07.clj +++ b/src/adventofcode2019/day07.clj @@ -1,65 +1,53 @@ (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)) + [clojure.math.combinatorics :as combo] + [clojure.core.async :as a]]) ;; 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] +(defn decode-op [opcode in out] (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])) + with-flags (fn [[f ac]] + [(case ac + 1 #(f %2 %1) + 2 #(f ((if f1 identity %1) %2) + ((if f2 identity %1) %3) %1) + 3 #(f ((if f1 identity %1) %2) + ((if f2 identity %1) %3) %4 %1)) ac])] + (with-flags + (case op + 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 (a/!! out (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])))) -(defn perform-operation [program counter] +(defn perform-operation [program counter in out] (let [opcode (program counter) - [operation arg-ct] (decode-op opcode) + [operation arg-ct] (decode-op opcode in out) args (->> (iterate inc counter) (rest) (take arg-ct) @@ -67,19 +55,35 @@ (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 intcode + ([program] + (intcode program nil nil)) + ([program in out] + (loop [[program counter] [program 0]] + (let [opcode (program counter)] + (if (= opcode 99) + program + (recur (perform-operation program counter in out))))))) (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 ))) + phase-settings-1 (combo/permutations [0 1 2 3 4]) + phase-settings-2 (combo/permutations [5 6 7 8 9]) + channels (->> #(a/chan 2) + (repeatedly 5) + (cycle)) + all-outputs-1 (for [settings phase-settings-1] + (do (doall (map a/>!! channels settings)) + (a/>!! (first channels) 0) + (doall (map intcode (repeat 5 input) channels (rest channels))) + (a/!! channels settings)) + (a/>!! (first channels) 0) + (a/