1 (ns adventofcode2019.day11
2 [:require [adventofcode2019.lib :refer :all]
3 [adventofcode2019.intcode :as i]
4 [clojure.string :as str]
5 [clojure.core.match :refer [match]]])
7 (defn painterbot-9000 [program input]
8 (let [stop-on-output #(= (count (:output %)) 2)
9 get-next-ic-output (partial i/intcode-until stop-on-output)
10 start-state (i/build-state program {:input [input]})
11 rotate (fn [heading turning]
12 (match [heading turning]
21 travel (fn [[x y] heading]
27 (loop [program-state (get-next-ic-output start-state)
31 (if (:exit program-state)
33 (let [[color direction] (:output program-state)
34 new-heading (rotate heading direction)
35 new-position (travel position new-heading)
36 prep-state (assoc program-state
38 :input [(get tileset new-position 0)])]
39 (recur (get-next-ic-output prep-state)
40 (assoc tileset position color)
41 new-position new-heading))))))
43 (defn find-bounds [tiles]
44 (let [x-list (map first (keys tiles))
45 y-list (map second (keys tiles))
46 min-x (reduce min x-list)
47 max-x (reduce max x-list)
48 min-y (reduce min y-list)
49 max-y (reduce max y-list)]
50 [[min-x max-x] [min-y max-y]]))
52 (defn make-field [[dx dy]]
53 (let [line (vec (repeat dx \space))]
54 (mapv (constantly line) (range dy))))
56 (defn draw-tiles [tiles]
57 (let [[[min-x max-x] [min-y max-y]] (find-bounds tiles)
58 to-text #(match % 0 \space
59 1 \u2588) ; full-block
60 field (make-field [(- max-x min-x -1) (- max-y min-y -1)])
61 paint-tile (fn [field [x y] color]
62 (assoc-in field [(- y min-y) (- x min-x)] (to-text color)))]
63 (mapv str/join (reduce-kv paint-tile field tiles))))
66 (let [input (mapv parse-int (get-list-from-file (input-file) #","))
67 painted-tiles (painterbot-9000 input 0)
68 reg-id-tiles (painterbot-9000 input 1)]
69 (part1 (count painted-tiles))
71 (run! println (draw-tiles reg-id-tiles))))