(ns adventofcode2019.day05 [:require [adventofcode2019.lib :refer :all] [clojure.string :as str]]) ;; 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 (parse-int (read-line))) #(+ % 2)]) 1] 4 [(fn [a mem] (println (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 day05 [] (let [input (mapv parse-int (get-list-from-file (input-file) #","))] (part1 "(input `1`)") (intcode input) (part2 "(input `5`)") (intcode input)))