]>
Commit | Line | Data |
---|---|---|
15f6c3bb JK |
1 | (ns adventofcode2019.day13 |
2 | [:require [adventofcode2019.lib :refer :all] | |
3 | [adventofcode2019.intcode :as i] | |
4 | [clojure.string :as str] | |
5 | [clojure.core.match :refer [match]] | |
ab32e543 JK |
6 | [clojure.math.combinatorics :as combo] |
7 | [lanterna.terminal :as ts]]) | |
8 | ||
9 | (def term (ts/get-terminal :text)) | |
10 | ||
11 | (defn find-bounds [tiles] | |
12 | (let [x-list (map first (keys tiles)) | |
13 | y-list (map second (keys tiles)) | |
14 | min-x (reduce min x-list) | |
15 | max-x (reduce max x-list) | |
16 | min-y (reduce min y-list) | |
17 | max-y (reduce max y-list)] | |
18 | [[min-x max-x] [min-y max-y]])) | |
19 | ||
20 | (defn make-field [[dx dy]] | |
21 | (let [line (vec (repeat dx \space))] | |
22 | (mapv (constantly line) (range dy)))) | |
23 | ||
24 | (defn draw-tiles [tiles term] | |
25 | (let [to-text #(case % | |
26 | 0 \space | |
27 | 1 \| | |
28 | 2 \- | |
29 | 3 \_ | |
30 | 4 \O) | |
31 | paint-tile (fn [[[x y] tile]] | |
32 | (ts/move-cursor term x y) | |
33 | (ts/put-character term (to-text tile)))] | |
34 | (doall (map paint-tile tiles)))) | |
35 | ||
36 | (defn print-field [field score] | |
37 | (run! (comp println str/join) field) | |
38 | (println score) | |
39 | (flush)) | |
40 | ||
41 | (defn run-game [game [[min-x max-x] [min-y max-y]]] | |
42 | (let [wait-for-output #(= (count (:output %)) 3) | |
43 | get-next-ic-output (partial i/intcode-until wait-for-output) | |
44 | new-game (assoc game :input [0]) | |
45 | field (ts/get-terminal :swing)] | |
46 | (ts/start field) | |
47 | (ts/put-character field \a) | |
48 | (loop [program-state (get-next-ic-output new-game) | |
49 | score 0 | |
50 | framerate 0 | |
51 | ctr 0] | |
52 | (Thread/sleep framerate) | |
53 | (if (:exit program-state) | |
54 | (do (ts/stop field) | |
55 | score) | |
56 | (let [[x y t] (:output program-state) | |
57 | [new-score new-screen] (if (and (= x -1) (= y 0)) | |
58 | [t {}] | |
59 | [score {[x y] t}]) | |
60 | input (case (ts/get-key-blocking field {:interval 1 :timeout framerate}) | |
61 | \a -1 | |
62 | \d 1 | |
63 | 0)] | |
64 | (draw-tiles new-screen field) | |
65 | (recur (get-next-ic-output (assoc program-state | |
66 | :output [] | |
67 | :input [input])) | |
68 | new-score (if (> ctr 814) 100 0) (inc ctr))))))) | |
15f6c3bb JK |
69 | |
70 | (defn day13 [] | |
71 | (let [input (i/get-program (input-file)) | |
72 | output (:output (i/intcode (i/build-state input))) | |
73 | draw-tiles (fn [screen [x y t]] (assoc screen [x y] t)) | |
ab32e543 JK |
74 | screen (reduce draw-tiles {} (partition 3 output)) |
75 | game (assoc-in (i/build-state input {:step true}) [:memory 0] 2)] | |
76 | (part1 (count (filter #(= % 2) (vals screen)))) | |
77 | (part2 (run-game game (find-bounds screen))))) |