--- /dev/null
+(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 )))
(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]
([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*)))