You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.5 KiB
Clojure
48 lines
1.5 KiB
Clojure
(require '[clojure.string :as str])
|
|
|
|
(defn alu-parse-argument [arg]
|
|
(if (contains? #{\w \x \y \z} (first arg))
|
|
(str/join ["@" arg])
|
|
(read-string arg)))
|
|
|
|
(defn alu-parse-instruction [[ins arg1 arg2]]
|
|
(let [arg2-parsed (if (some? arg2) (alu-parse-argument arg2) 0)]
|
|
(case ins
|
|
"inp"
|
|
(str/join ["(reset! " arg1 " (- (int (get input (swap! index inc))) 48))\n"])
|
|
"add"
|
|
(str/join ["(swap! " arg1 " +' " arg2-parsed ")\n"])
|
|
"mul"
|
|
(str/join ["(swap! " arg1 " *' " arg2-parsed ")\n"])
|
|
"div"
|
|
(str/join ["(swap! " arg1 " quot " arg2-parsed ")\n"])
|
|
"mod"
|
|
(str/join ["(swap! " arg1 " rem " arg2-parsed ")\n"])
|
|
"eql"
|
|
(str/join ["(swap! " arg1 " #(if (= % " arg2-parsed ") 1 0))\n"]))))
|
|
|
|
(def alu-program-header
|
|
"(defn alu-program [input]
|
|
(let [index (atom -1) w (atom 0) x (atom 0) y (atom 0) z (atom 0)]\n")
|
|
|
|
(defn alu-compile-program [instructions]
|
|
(let [parsed-ins (mapv alu-parse-instruction instructions)]
|
|
(eval (read-string
|
|
(str/join [alu-program-header
|
|
(str/join parsed-ins)
|
|
"@z))"])))))
|
|
|
|
(def program (->> (slurp "./in")
|
|
str/split-lines
|
|
(map #(str/split % #"\s+"))
|
|
(alu-compile-program)))
|
|
|
|
; to split by `inp w`s:
|
|
; (partition 18)
|
|
; (reverse)
|
|
; (mapv alu-compile-program)))
|
|
|
|
(println "Part 1:" (program "16181111641521"))
|
|
(println "Part 2:" (program "59692994994998"))
|
|
|