-
Notifications
You must be signed in to change notification settings - Fork 0
/
day12.clj
62 lines (53 loc) · 1.54 KB
/
day12.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
(ns aoc.2022.day12
(:require
[loom.graph :as loom]
[loom.alg :as loom-alg]
[aoc.grid :as grid]
[aoc.core :as core :refer [read-input-lines]]
[medley.core :as m]))
(def sample (read-input-lines "2022/day12-sample.txt"))
(def input (read-input-lines "2022/day12.txt"))
(defn parse-cell [v]
(condp = v
"E" {:height (int \z) :end true}
"S" {:height (int \a) :start true}
{:height (int (first v))}))
(defn can-walk? [from-h to-h]
(when to-h
(or (= (inc from-h) to-h)
(<= to-h from-h))))
(defn terminal-node [g kw]
(first (m/find-first (fn [[pos v]]
(when (get v kw) pos)) g)))
(defn has-edge? [g from to]
(let [from-h (get-in g [from :height])
to-h (get-in g [to :height])]
(can-walk? from-h to-h)))
(defn solve [g start-nodes end]
(let [graph (loom/digraph (grid/adjacency-graph grid/adjacent-cardinal has-edge? g))]
(->> start-nodes
(map #(-> graph
(loom-alg/bf-path % end)
(rest)
(count)))
(filter #(> % 0))
(apply min))))
(defn part-1 [input]
(let [g (grid/to-grid input parse-cell)]
(solve g
#{(terminal-node g :start)}
(terminal-node g :end))))
(defn part-2 [input]
(let [g (grid/to-grid input parse-cell)
lowest-coords (keys (m/filter-vals #(= (int \a) (:height %)) g))]
(solve g
lowest-coords
(terminal-node g :end))))
(comment
(part-1 input)
;; => 380
(part-2 sample)
;; => 29
(part-2 input)
;; => 375
)