/
puzzle06.clj
88 lines (75 loc) · 2.33 KB
/
puzzle06.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
(ns advent.puzzle06)
(defn read-sample
[]
(with-open [f (-> "6/sample.txt"
clojure.java.io/reader)]
(vec (line-seq f))))
(defn read-input
[]
(with-open [f (-> "6/input.txt"
clojure.java.io/reader)]
(vec (line-seq f))))
(defn parse [xs]
(->> xs
(map #(clojure.string/split % #",\s*"))
(mapv (partial mapv #(Long/parseLong %)))))
(def width 358)
(def height 353)
(def threshold 10000)
(defn edge? [[x y]]
(or (= x 0)
(= y 0)
(= x (dec width))
(= y (dec height))))
(defn edge-locations []
(for [y (range height)
x (range width)
:when (edge? [x y])]
[x y]))
(defn color
"Takes a grid, a id and a coordinate [x y] and returns
a new grid with points representing distance to coordinate"
[grid id [coord-x coord-y]]
(->> (for [y (range height)
x (range width)]
(let [[old-id old-distance :as v] (get grid [x y])
distance (+ (Math/abs (- coord-x x))
(Math/abs (- coord-y y)))]
[[x y]
(cond
(or (nil? v) (< distance old-distance))
[id distance]
(= distance old-distance)
[nil distance]
:else
[old-id old-distance])]))
(into {})))
(defn solution-1 []
(let [grid (->> (read-input)
parse
(map-indexed vector)
(reduce (fn [grid [id coord]]
(color grid id coord))
{}))
candidates (->> grid vals (keep first) frequencies)
disqualified (->> (edge-locations)
(map grid)
(keep first)
set)]
(apply max (keep (fn [[id area]]
(when-not (disqualified id)
area))
candidates))))
(defn total-distance [[x y] coords]
(->> coords
(map (fn [[coord-x coord-y]]
(+ (Math/abs (- coord-x x))
(Math/abs (- coord-y y)))))
(apply +)))
(defn solution-2 []
(let [coords (->> (read-input) parse)]
(->> (for [y (range height)
x (range width)]
(total-distance [x y] coords))
(filter (fn [total-distance] (< total-distance threshold)))
count)))