From d0f13cd27088cf370a59e78e8438bef9bbddb13e Mon Sep 17 00:00:00 2001 From: Jack Kinsey Date: Sat, 7 Dec 2019 15:32:48 -0500 Subject: [PATCH] Add correct day7pt1 Also, start work on an input file getter in lib. --- .gitignore | 1 + resources/day07 | 1 + src/adventofcode2019/core.clj | 3 +- src/adventofcode2019/day07.clj | 85 ++++++++++++++++++++++++++++++++++ src/adventofcode2019/lib.clj | 32 +++++++++++-- 5 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 resources/day07 create mode 100644 src/adventofcode2019/day07.clj diff --git a/.gitignore b/.gitignore index d18f225..78c1a87 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ pom.xml.asc /.nrepl-port .hgignore .hg/ +token diff --git a/resources/day07 b/resources/day07 new file mode 100644 index 0000000..fcbe739 --- /dev/null +++ b/resources/day07 @@ -0,0 +1 @@ +3,8,1001,8,10,8,105,1,0,0,21,34,47,72,93,110,191,272,353,434,99999,3,9,102,3,9,9,1001,9,3,9,4,9,99,3,9,102,4,9,9,1001,9,4,9,4,9,99,3,9,101,3,9,9,1002,9,3,9,1001,9,2,9,1002,9,2,9,101,4,9,9,4,9,99,3,9,1002,9,3,9,101,5,9,9,102,4,9,9,1001,9,4,9,4,9,99,3,9,101,3,9,9,102,4,9,9,1001,9,3,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,99 diff --git a/src/adventofcode2019/core.clj b/src/adventofcode2019/core.clj index aeabe1d..f4cc833 100644 --- a/src/adventofcode2019/core.clj +++ b/src/adventofcode2019/core.clj @@ -1,6 +1,7 @@ (ns adventofcode2019.core [:require (adventofcode2019 day01 day02 day03 - day04 day05 day06)]) + day04 day05 day06 + day07)]) (defn -main ([] 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 ))) diff --git a/src/adventofcode2019/lib.clj b/src/adventofcode2019/lib.clj index 834893c..2699439 100644 --- a/src/adventofcode2019/lib.clj +++ b/src/adventofcode2019/lib.clj @@ -1,6 +1,7 @@ (ns adventofcode2019.lib [:require [clojure.string :as str] - [clojure.java.io :as io]]) + [clojure.java.io :as io] + [clojure.java.shell :refer [sh]]]) (defn get-list-from-file ([file-name] @@ -8,14 +9,37 @@ ([file-name split-regex] (str/split (str/trim (slurp file-name)) split-regex))) +(def parse-int + #(Integer/parseInt %)) + (defmacro input-file [] (let [bottom-ns (last (str/split (str *ns*) #"\."))] (str "resources/" bottom-ns))) -(def parse-int - #(Integer/parseInt %)) - (def part1 #(println (str "Part 1: " %))) (def part2 #(println (str "Part 2: " %))) + +;; FIXME: this is still broken but i give up for now +; (defn --input-file [for-ns] +; (let [bottom-ns (last (str/split for-ns #"\.")) +; input-url "https://adventofcode.com/2019/day/%d/input" +; day-url (->> bottom-ns +; (drop 3) +; (str/join) +; (parse-int) +; (format input-url)) +; token (str/trim (slurp (io/resource "token"))) +; res-dir (-> (io/resource "token") +; (.getPath) +; (str/replace "token" bottom-ns)) +; cmd ["curl" "-s" "-b" +; (format "\"session=%s\"" token) +; day-url ">" res-dir]] +; (if-let [input (io/resource bottom-ns)] +; input +; (do (apply sh cmd) nil)))) + +; (defmacro input-file [] +; (--input-file (str *ns*))) -- 2.26.2