From 9a22e14c7830c284c4d6f8fa402734908a128458 Mon Sep 17 00:00:00 2001 From: Jack Kinsey Date: Sat, 7 Dec 2019 17:34:03 -0500 Subject: [PATCH] Add correct day7pt2 --- project.clj | 3 +- src/adventofcode2019/day07.clj | 132 +++++++++++++++++---------------- 2 files changed, 70 insertions(+), 65 deletions(-) diff --git a/project.clj b/project.clj index df6ecc5..6de5bc2 100644 --- a/project.clj +++ b/project.clj @@ -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}}) 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/