(ns adventofcode2019.day11 [:require [adventofcode2019.lib :refer :all] [adventofcode2019.intcode :as i] [clojure.string :as str] [clojure.core.match :refer [match]]]) (defn painterbot-9000 [program input] (let [stop-on-output #(= (count (:output %)) 2) get-next-ic-output (partial i/intcode-until stop-on-output) start-state (i/build-state program {:input [input]}) rotate (fn [heading turning] (match [heading turning] [:up 0] :left [:down 0] :right [:left 0] :down [:right 0] :up [:up 1] :right [:down 1] :left [:left 1] :up [:right 1] :down)) travel (fn [[x y] heading] (case heading :up [x (dec y)] :down [x (inc y)] :left [(dec x) y] :right [(inc x) y]))] (loop [program-state (get-next-ic-output start-state) tileset {} position [0 0] heading :up] (if (:exit program-state) tileset (let [[color direction] (:output program-state) new-heading (rotate heading direction) new-position (travel position new-heading) prep-state (assoc program-state :output [] :input [(get tileset new-position 0)])] (recur (get-next-ic-output prep-state) (assoc tileset position color) new-position new-heading)))))) (defn find-bounds [tiles] (let [x-list (map first (keys tiles)) y-list (map second (keys tiles)) min-x (reduce min x-list) max-x (reduce max x-list) min-y (reduce min y-list) max-y (reduce max y-list)] [[min-x max-x] [min-y max-y]])) (defn make-field [[dx dy]] (let [line (vec (repeat dx \space))] (mapv (constantly line) (range dy)))) (defn draw-tiles [tiles] (let [[[min-x max-x] [min-y max-y]] (find-bounds tiles) to-text #(match % 0 \space 1 \u2588) ; full-block field (make-field [(- max-x min-x -1) (- max-y min-y -1)]) paint-tile (fn [field [x y] color] (assoc-in field [(- y min-y) (- x min-x)] (to-text color)))] (mapv str/join (reduce-kv paint-tile field tiles)))) (defn day11 [] (let [input (mapv parse-int (get-list-from-file (input-file) #",")) painted-tiles (painterbot-9000 input 0) reg-id-tiles (painterbot-9000 input 1)] (part1 (count painted-tiles)) (part2 "see below") (run! println (draw-tiles reg-id-tiles))))