Skip to content

Commit 96d7fe8

Browse files
committed
Day 23 solutions
1 parent 688652f commit 96d7fe8

File tree

5 files changed

+3549
-4
lines changed

5 files changed

+3549
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,4 @@ This should start the server at `localhost:8080`.
108108
❄️ [Day 20](aoc-solver/src/y2024/day20.rs)
109109
❄️ [Day 21](aoc-solver/src/y2024/day21.rs)
110110
❄️ [Day 22](aoc-solver/src/y2024/day22.rs)
111+
❄️ [Day 23](aoc-solver/src/y2024/day23.rs)

aoc-solver/src/y2024/day23.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
use std::collections::{HashMap, HashSet};
2+
3+
use crate::solution::{AocError, Solution};
4+
5+
fn parse(input: &str) -> Result<HashMap<&str, HashSet<&str>>, AocError> {
6+
let mut network: HashMap<&str, HashSet<&str>> = HashMap::new();
7+
8+
for row in input.lines() {
9+
let (first, second) = row
10+
.split_once("-")
11+
.ok_or_else(|| AocError::parse(row, "Invalid network node"))?;
12+
13+
network.entry(first).or_default().insert(second);
14+
network.entry(second).or_default().insert(first);
15+
}
16+
17+
Ok(network)
18+
}
19+
20+
pub struct Day23;
21+
impl Solution for Day23 {
22+
type A = u32;
23+
type B = String;
24+
25+
fn default_input(&self) -> &'static str {
26+
include_str!("../../../inputs/2024/day23.txt")
27+
}
28+
29+
fn part_1(&self, input: &str) -> Result<u32, AocError> {
30+
let network = parse(input)?;
31+
32+
let mut networks_of_three: HashSet<Vec<&str>> = HashSet::new();
33+
34+
for (first, edges) in network.iter() {
35+
if first.starts_with("t") {
36+
for second in edges {
37+
for third in network[second].intersection(edges) {
38+
let mut group = vec![*first, *second, *third];
39+
group.sort();
40+
networks_of_three.insert(group);
41+
}
42+
}
43+
}
44+
}
45+
46+
Ok(networks_of_three.len() as u32)
47+
}
48+
49+
fn part_2(&self, input: &str) -> Result<String, AocError> {
50+
let network = parse(input)?;
51+
52+
let mut largest = network
53+
.iter()
54+
.map(|(current, edges)| {
55+
let mut interconnected = vec![*current];
56+
57+
for edge in edges {
58+
if interconnected
59+
.iter()
60+
.all(|node| network[edge].contains(node))
61+
{
62+
interconnected.push(*edge);
63+
}
64+
}
65+
66+
interconnected
67+
})
68+
.max_by(|a, b| a.len().cmp(&b.len()))
69+
.ok_or_else(|| AocError::logic("No groups found"))?;
70+
71+
largest.sort();
72+
let password = largest.join(",");
73+
74+
Ok(password)
75+
}
76+
}
77+
78+
#[cfg(test)]
79+
mod tests {
80+
use super::*;
81+
82+
#[test]
83+
fn it_solves_part1_example() {
84+
assert_eq!(
85+
Day23.part_1(
86+
"kh-tc\n\
87+
qp-kh\n\
88+
de-cg\n\
89+
ka-co\n\
90+
yn-aq\n\
91+
qp-ub\n\
92+
cg-tb\n\
93+
vc-aq\n\
94+
tb-ka\n\
95+
wh-tc\n\
96+
yn-cg\n\
97+
kh-ub\n\
98+
ta-co\n\
99+
de-co\n\
100+
tc-td\n\
101+
tb-wq\n\
102+
wh-td\n\
103+
ta-ka\n\
104+
td-qp\n\
105+
aq-cg\n\
106+
wq-ub\n\
107+
ub-vc\n\
108+
de-ta\n\
109+
wq-aq\n\
110+
wq-vc\n\
111+
wh-yn\n\
112+
ka-de\n\
113+
kh-ta\n\
114+
co-tc\n\
115+
wh-qp\n\
116+
tb-vc\n\
117+
td-yn"
118+
),
119+
Ok(7)
120+
);
121+
}
122+
123+
#[test]
124+
fn it_solves_part2_example() {
125+
assert_eq!(
126+
Day23.part_2(
127+
"kh-tc\n\
128+
qp-kh\n\
129+
de-cg\n\
130+
ka-co\n\
131+
yn-aq\n\
132+
qp-ub\n\
133+
cg-tb\n\
134+
vc-aq\n\
135+
tb-ka\n\
136+
wh-tc\n\
137+
yn-cg\n\
138+
kh-ub\n\
139+
ta-co\n\
140+
de-co\n\
141+
tc-td\n\
142+
tb-wq\n\
143+
wh-td\n\
144+
ta-ka\n\
145+
td-qp\n\
146+
aq-cg\n\
147+
wq-ub\n\
148+
ub-vc\n\
149+
de-ta\n\
150+
wq-aq\n\
151+
wq-vc\n\
152+
wh-yn\n\
153+
ka-de\n\
154+
kh-ta\n\
155+
co-tc\n\
156+
wh-qp\n\
157+
tb-vc\n\
158+
td-yn"
159+
),
160+
Ok(String::from("co,de,ka,ta"))
161+
);
162+
}
163+
}

aoc-solver/src/y2024/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ pub mod day19;
2222
pub mod day20;
2323
pub mod day21;
2424
pub mod day22;
25-
// pub mod day23;
25+
pub mod day23;
2626
// pub mod day24;
2727
// pub mod day25;
2828

29-
pub const MAX_DAYS: u8 = 22;
29+
pub const MAX_DAYS: u8 = 23;
3030

3131
pub struct Y2024;
3232

@@ -55,7 +55,7 @@ impl Solver for Y2024 {
5555
20 => day20::Day20.run(input, 20, 2024),
5656
21 => day21::Day21.run(input, 21, 2024),
5757
22 => day22::Day22.run(input, 22, 2024),
58-
// 23 => day23::Day23.run(input, 23, 2024),
58+
23 => day23::Day23.run(input, 23, 2024),
5959
// 24 => day24::Day24.run(input, 24, 2024),
6060
// 25 => day25::Day25.run(input, 25, 2024),
6161
_ => vec![String::from("Solution not implemented (yet?)")],
@@ -97,7 +97,7 @@ impl Solver for Y2024 {
9797
20 => include_str!("./day20.rs"),
9898
21 => include_str!("./day21.rs"),
9999
22 => include_str!("./day22.rs"),
100-
// 23 => include_str!("./day23.rs"),
100+
23 => include_str!("./day23.rs"),
101101
// 24 => include_str!("./day24.rs"),
102102
// 25 => include_str!("./day25.rs"),
103103
_ => unimplemented!(),

aoc-web/src/header.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub fn header(props: &HeaderProps) -> Html {
4343
<NavLink route={Route::Solution { year: 2024, day: 20 }} current={props.route.clone()} text={"20"}/>
4444
<NavLink route={Route::Solution { year: 2024, day: 21 }} current={props.route.clone()} text={"21"}/>
4545
<NavLink route={Route::Solution { year: 2024, day: 22 }} current={props.route.clone()} text={"22"}/>
46+
<NavLink route={Route::Solution { year: 2024, day: 23 }} current={props.route.clone()} text={"23"}/>
4647
</>
4748
}
4849
},

0 commit comments

Comments
 (0)