Add correct day7pt2
authorJack Kinsey <j.jameskinsey@gmail.com>
Sat, 7 Dec 2019 22:34:03 +0000 (17:34 -0500)
committerJack Kinsey <j.jameskinsey@gmail.com>
Sat, 7 Dec 2019 22:34:03 +0000 (17:34 -0500)
project.clj
src/adventofcode2019/day07.clj

index df6ecc57b62170e6f34de7c9732ea2bd784ccb9e..6de5bc22c5496aee9643011b44a8d9d101b08323 100644 (file)
@@ -5,7 +5,8 @@
 ;;          :url "https://www.eclipse.org/legal/epl-2.0/"}
   :dependencies [[org.clojure/clojure "1.10.0"]
                  [org.clojure/core.match "0.3.0"]
-                 [org.clojure/math.combinatorics "0.1.6"]]
+                 [org.clojure/math.combinatorics "0.1.6"]
+                 [org.clojure/core.async "0.6.532"]]
   :main ^:skip-aot adventofcode2019.core
   :target-path "target/%s"
   :profiles {:uberjar {:aot :all}})
index 9b43cc4987229cae78afd7375fb7ad3006458b8c..d2617f72d3e4cf3013c3db9c8d45f5359d46b6df 100644 (file)
@@ -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/<!! in)) #(+ % 2)])
+           1]
+        4 [(fn [a mem] 
+               (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) 
      (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/<!! (first channels))))
+        all-outputs-2 (for [settings phase-settings-2]
+                           (do (doall (map a/>!! channels settings))
+                               (a/>!! (first channels) 0)
+                               (a/<!! (last (for [[prog in out] 
+                                                  (map vector (repeat 5 input) channels (rest channels))] 
+                                                 (a/thread
+                                                   (intcode prog in out)))))
+                               (a/<!! (first channels))))]
+    (part1 (apply max all-outputs-1)) 
+    (part2 (apply max all-outputs-2))))