Skip to content

Commit 6efdfa4

Browse files
committed
day25.clj
1 parent 15dc474 commit 6efdfa4

File tree

5 files changed

+1329
-2
lines changed

5 files changed

+1329
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Day 00: Helper file | [aoc.clj](clojure/aoc.clj) |
6161
[Day 22](http://adventofcode.com/2023/day/22) | [day22.clj](clojure/day22.clj) | Jenga!
6262
[Day 23](http://adventofcode.com/2023/day/23) | [day23.clj](clojure/day23.clj) | Compressing the graph for part 2.
6363
[Day 24](http://adventofcode.com/2023/day/24) | [day24.clj](clojure/day24.clj) | Don't ask me how this works.
64-
<!-- [Day 25](http://adventofcode.com/2023/day/25) | [day25.clj](clojure/day25.clj) | -->
64+
[Day 25](http://adventofcode.com/2023/day/25) | [day25.clj](clojure/day25.clj) | Monte Carlo to find "hot" edges.
6565

6666

6767
&nbsp;

clojure/day25.clj

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
(ns day25
2+
(:require aoc))
3+
4+
5+
(defn build-graph [components]
6+
(let [adjacencies (atom {})]
7+
(doseq [[k & vs] components
8+
v vs]
9+
(swap! adjacencies update k conj v)
10+
(swap! adjacencies update v conj k))
11+
@adjacencies))
12+
13+
14+
(defn add-edges [edge-counts vs]
15+
(reduce (fn [edge-counts [a b]]
16+
(update edge-counts (sort [a b]) (fnil inc 0)))
17+
edge-counts
18+
(partition 2 1 vs)))
19+
20+
(defn traverse [graph start end edge-counts]
21+
(loop [queue (conj aoc/empty-queue [start []])
22+
seen #{}]
23+
(if-let [[curr prevs] (peek queue)]
24+
(cond
25+
(= curr end) (add-edges edge-counts (conj prevs curr))
26+
(seen curr) (recur (pop queue) seen)
27+
:else (recur (into (pop queue) (map (fn [x] [x (conj prevs curr)])
28+
(graph curr)))
29+
(conj seen curr)))
30+
(count seen))))
31+
32+
(defn find-most-frequent-edges [graph]
33+
(reduce (fn [edge-counts [start end]]
34+
(traverse graph start end edge-counts))
35+
{}
36+
(repeatedly 200 #(shuffle (keys graph)))))
37+
38+
(defn remove-most-frequent [edge-counts graph]
39+
(let [most-frequent (keys (take 3 (sort-by val > edge-counts)))]
40+
(reduce (fn [graph [a b]]
41+
(-> graph
42+
(update a (fn [nbs] (remove #{b} nbs)))
43+
(update b (fn [nbs] (remove #{a} nbs)))))
44+
graph
45+
most-frequent)))
46+
47+
(defn find-groups [graph]
48+
(let [edge-counts (find-most-frequent-edges graph)
49+
graph' (remove-most-frequent edge-counts graph)
50+
total-nodes (count (keys graph))
51+
island (traverse graph' (key (first graph)) nil nil)]
52+
(* (- total-nodes island) island)))
53+
54+
55+
(defn solve [input-file]
56+
(let [components (aoc/parse-input input-file :words {:word-sep #": | "})
57+
graph (build-graph components)]
58+
(find-groups graph)))
59+
60+
61+
(solve (aoc/read-file 25))

clojure/tests/solutions_tests.clj

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
day06 day07 day08 day09 day10
55
day11 day12 day13 day14 day15
66
day16 day17 day18 day19 day20
7-
day21 day22 day23 day24 ;day25
7+
day21 day22 day23 day24 day25
88
[clojure.test :refer [deftest is run-tests successful?]]))
99

1010

@@ -48,6 +48,7 @@
4848
(check-day 22 [5 7] [418 70702])
4949
(check-day 23 nil [2394 6554])
5050
(check-day 24 nil [13892 843888100572888])
51+
(check-day 25 54 603368)
5152

5253

5354
(let [summary (run-tests)]

0 commit comments

Comments
 (0)