Skip to content

Commit 9c63725

Browse files
committed
Day 23
1 parent bf2949b commit 9c63725

File tree

4 files changed

+156
-2
lines changed

4 files changed

+156
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
1010

1111
| Year | Completed |
1212
| :---: | :---: |
13-
| [2024](aoc2024) | 44/50 |
13+
| [2024](aoc2024) | 46/50 |
1414
| [2023](aoc2023) | 50/50 |
1515

1616
---

aoc2024/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2828
| [Day 20](https://adventofcode.com/2024/day/20) | [code](src/bin/20.rs) |||
2929
| [Day 21](https://adventofcode.com/2024/day/21) | [code](src/bin/21.rs) |||
3030
| [Day 22](https://adventofcode.com/2024/day/22) | [code](src/bin/22.rs) |||
31-
| [Day 23](https://adventofcode.com/2024/day/23) | [code](src/bin/23.rs) | _ | _ |
31+
| [Day 23](https://adventofcode.com/2024/day/23) | [code](src/bin/23.rs) | | |
3232
| [Day 24](https://adventofcode.com/2024/day/24) | [code](src/bin/24.rs) | _ | _ |
3333
| [Day 25](https://adventofcode.com/2024/day/25) | [code](src/bin/25.rs) | _ | _ |
3434

aoc2024/data/examples/23.txt

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
kh-tc
2+
qp-kh
3+
de-cg
4+
ka-co
5+
yn-aq
6+
qp-ub
7+
cg-tb
8+
vc-aq
9+
tb-ka
10+
wh-tc
11+
yn-cg
12+
kh-ub
13+
ta-co
14+
de-co
15+
tc-td
16+
tb-wq
17+
wh-td
18+
ta-ka
19+
td-qp
20+
aq-cg
21+
wq-ub
22+
ub-vc
23+
de-ta
24+
wq-aq
25+
wq-vc
26+
wh-yn
27+
ka-de
28+
kh-ta
29+
co-tc
30+
wh-qp
31+
tb-vc
32+
td-yn

aoc2024/src/bin/23.rs

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use std::collections::{HashMap, HashSet};
2+
3+
advent_of_code::solution!(23);
4+
5+
fn parse_input(input: &str) -> HashMap<&str, Vec<&str>> {
6+
let mut cons: HashMap<&str, Vec<&str>> = HashMap::new();
7+
input.lines().for_each(|l| {
8+
let comps = l.split_once("-").expect("Split should work");
9+
cons.entry(comps.0)
10+
.and_modify(|v| v.push(comps.1))
11+
.or_insert(vec![comps.1]);
12+
cons.entry(comps.1)
13+
.and_modify(|v| v.push(comps.0))
14+
.or_insert(vec![comps.0]);
15+
});
16+
cons
17+
}
18+
19+
pub fn part_one(input: &str) -> Option<u64> {
20+
let cons = parse_input(input);
21+
let mut threes = HashSet::new();
22+
cons.iter()
23+
.filter(|x| x.0.starts_with("t"))
24+
.for_each(|(&k, v)| {
25+
v.iter().for_each(|&k2| {
26+
cons.get(k2)
27+
.unwrap()
28+
.iter()
29+
.filter(|&&k3| k3 != k)
30+
.for_each(|&k3| {
31+
if cons.get(k3).unwrap().contains(&k) {
32+
let mut new = [k, k2, k3];
33+
new.sort();
34+
threes.insert(new);
35+
}
36+
})
37+
})
38+
});
39+
Some(threes.len() as u64)
40+
}
41+
42+
fn largest_containing<'a>(
43+
containing: Vec<&'a str>,
44+
tried_containing: &mut HashSet<String>,
45+
cons: &'a HashMap<&'a str, Vec<&'a str>>,
46+
) -> String {
47+
let item = containing.iter().next().unwrap();
48+
let v = cons.get(item).unwrap();
49+
let res = v
50+
.iter()
51+
.filter_map(|&k| {
52+
if containing.contains(&k) {
53+
return None;
54+
}
55+
let other_v = cons.get(k).unwrap();
56+
for j in containing.iter() {
57+
if !other_v.contains(j) {
58+
return None;
59+
}
60+
}
61+
let mut new_containing = containing.clone();
62+
new_containing.push(k);
63+
new_containing.sort();
64+
let as_string = new_containing.join(",");
65+
if tried_containing.contains(&as_string) {
66+
return None;
67+
}
68+
tried_containing.insert(as_string);
69+
Some(largest_containing(new_containing, tried_containing, cons))
70+
})
71+
.fold(
72+
String::new(),
73+
|acc, s| {
74+
if s.len() > acc.len() {
75+
s
76+
} else {
77+
acc
78+
}
79+
},
80+
);
81+
if res.is_empty() {
82+
containing.join(",")
83+
} else {
84+
res
85+
}
86+
}
87+
88+
pub fn part_two(input: &str) -> Option<String> {
89+
let cons = parse_input(input);
90+
let mut seen_sets = HashSet::new();
91+
let largest = cons
92+
.keys()
93+
.map(|&k| largest_containing(vec![k], &mut seen_sets, &cons))
94+
.fold(
95+
String::new(),
96+
|acc, s| {
97+
if s.len() > acc.len() {
98+
s
99+
} else {
100+
acc
101+
}
102+
},
103+
);
104+
Some(largest)
105+
}
106+
107+
#[cfg(test)]
108+
mod tests {
109+
use super::*;
110+
111+
#[test]
112+
fn test_part_one() {
113+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
114+
assert_eq!(result, Some(7));
115+
}
116+
117+
#[test]
118+
fn test_part_two() {
119+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
120+
assert_eq!(result, Some("co,de,ka,ta".to_string()));
121+
}
122+
}

0 commit comments

Comments
 (0)