-
Notifications
You must be signed in to change notification settings - Fork 2
/
2.clj
129 lines (115 loc) · 3.85 KB
/
2.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
(ns advent-of-code.2018.2
(:require [advent-of-code.elves :refer :all]
[clojure.set :as set]
[clojure.math.combinatorics :as comb]))
(def lines (day->input-lines 2018 2))
;; solve part one
(defn score-box-id [id]
(let [{has-2 2 has-3 3} (set/map-invert (frequencies id))]
(cond
(and has-2 has-3) :both
has-2 :two
has-3 :three)))
(let [{:keys [two three both]} (group-by score-box-id lines)]
(* (+ (count two) (count both))
(+ (count three) (count both))))
;; solve part two
(defn diff-indices [a b]
(keep identity
(map (fn [x y z] (when-not (= x y) z))
a b (range))))
(first
(for [[l r] (comb/combinations lines 2)
:let [diff (diff-indices l r)]
:when (= 1 (count diff))]
(str (subs l 0 (first diff))
(subs l (inc (first diff))))))
(comment
"Render animated visualization solving part two; probably buggy."
(require '[quil.middleware :as m]
'[quil.core :as q])
(def font-size 24)
(defn replace-chars [s smap]
(->> (mapcat identity smap)
(apply assoc (vec s))
(apply str)))
(defn update-line-state [state]
(if-let [[l r diff] (:curr-line state)]
(let [mask (-> l
(replace-chars
(into {} (for [i (range (count l))
:when (not (contains? (set diff) i))]
[i " "]))))]
(assoc state
:left (replace-chars l (apply hash-map (interleave diff (repeat " "))))
:mask mask
:mask-trail (vec (take 20 (cons mask (:mask-trail state))))
:right r
:diff diff))
state))
(defn update-state [state]
(cond-> state
(not (:end? state))
(assoc :lines (rest (:lines state))
:curr-line (first (:lines state)))
(not-empty (:lines state))
(update-line-state)
(let [[l r] (:curr-line state)
diff (diff-indices l r)]
(= 1 (count diff)))
(assoc :match? true
:end? true)
(empty? (:lines state))
(assoc :end? true)))
(defn draw-state [state]
(q/fill 0 40)
(q/rect 0 0 (q/width) (q/height))
(if (:match? state)
(q/fill 255)
(q/fill 234 207 76))
(let [{:keys [left right mask mask-trail]} state
left-y (- (q/height) (* 2 font-size))
right-y (+ left-y font-size)]
(when (and left right mask)
;; render left string
(q/text left
(- (/ (q/width) 2)
(/ (q/text-width left) 2))
left-y)
;; render right string
(q/text right
(- (/ (q/width) 2)
(/ (q/text-width right) 2))
right-y)
;; render differing characters in white
(q/fill 255 0 0)
(q/text mask
(- (/ (q/width) 2)
(/ (q/text-width mask) 2))
left-y)
;; render trail of previous mask diffs
(dotimes [i (count mask-trail)]
(q/fill (q/random 200 255) 0 0 (- 255 (* i (/ 255 (count mask-trail)))))
(let [mask (nth mask-trail i)]
(q/text mask
(- (/ (q/width) 2)
(/ (q/text-width mask) 2))
(- left-y
(* (inc i) font-size)))))))
(when (or (:match? state) (:end? state))
(q/no-loop)))
(defn setup []
(q/frame-rate 24)
(q/background 0)
(q/text-font (q/create-font "Courier New" font-size true))
{:lines (for [[l r] (comb/combinations lines 2)
:let [diff (diff-indices l r)]]
[l r diff])})
(q/defsketch matrix
:title "Inventory Management System"
:size [500 500]
:setup setup
:update update-state
:draw draw-state
:features [:keep-on-top :resizable]
:middleware [m/fun-mode]))