Fix day5pt1 and add correct day5pt2
[adventofcode2019.git] / src / adventofcode2019 / day05.clj
CommitLineData
3c432ae2 1(ns adventofcode2019.day05
8d5bfece
JK
2 [:require [adventofcode2019.lib :refer :all]
3 [clojure.string :as str]])
4
3c432ae2
JK
5;; 0: function args&mem -> [mem (ctr -> ctr)]
6;; 1: number of args
7(def operations {1 [(fn [a b c mem]
8 [(assoc mem c (+ a b)) #(+ % 4)])
9 3]
10 2 [(fn [a b c mem]
11 [(assoc mem c (* a b)) #(+ % 4)])
12 3]
13 3 [(fn [a mem]
14 [(assoc mem a (parse-int (read-line))) #(+ % 2)])
15 1]
16 4 [(fn [a mem]
17 (println (mem a))
18 [mem #(+ % 2)])
19 1]
20 5 [(fn [a b mem]
21 [mem (if (not= a 0) (constantly b) #(+ % 3))])
22 2]
23 6 [(fn [a b mem]
24 [mem (if (= a 0) (constantly b) #(+ % 3))])
25 2]
26 7 [(fn [a b c mem]
27 [(assoc mem c (if (< a b) 1 0)) #(+ % 4)])
28 3]
29 8 [(fn [a b c mem]
30 [(assoc mem c (if (= a b) 1 0)) #(+ % 4)])
31 3]})
32
33;; FIXME: sorry about the dropped forms i didn't want to fix it properly
34;; the problem is that flags don't apply to certain args for certain ops
35(defn decode-op [opcode]
8d5bfece
JK
36 (let [str-code (format "%05d" opcode)
37 [f3 f2 f1] (map #(= \1 %) (take 3 str-code))
38 op (parse-int (str/join (drop 3 str-code)))
39 [operation arg-ct] (operations op)]
40 [(case arg-ct
3c432ae2
JK
41 1 #(operation #_((if f1 identity %1) %2) %2 %1)
42 2 #(operation ((if f1 identity %1) %2)
43 ((if f2 identity %1) %3) %1)
8d5bfece
JK
44 3 #(operation ((if f1 identity %1) %2)
45 ((if f2 identity %1) %3)
3c432ae2
JK
46 #_((if f3 identity %1) %4) %4 %1))
47 arg-ct]))
8d5bfece
JK
48
49(defn perform-operation [program counter]
50 (let [opcode (program counter)
51 [operation arg-ct] (decode-op opcode)
52 args (->> (iterate inc counter)
53 (rest)
54 (take arg-ct)
55 (map program))]
3c432ae2
JK
56 (let [[program ctr-update] (apply operation program args)]
57 [program (ctr-update counter)])))
8d5bfece
JK
58
59(defn intcode [program]
60 (loop [[program counter] [program 0]]
61 (let [opcode (program counter)]
62 (if (= opcode 99)
63 program
64 (recur (perform-operation program counter))))))
65
3c432ae2 66(defn day05 []
8d5bfece 67 (let [input (mapv parse-int (get-list-from-file (input-file) #","))]
3c432ae2
JK
68 (part1 "(input `1`)")
69 (intcode input)
70 (part2 "(input `5`)")
71 (intcode input)))