Skip to content

Commit ddb47ac

Browse files
committed
23th day (brute force)
1 parent 593782d commit ddb47ac

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed

data/examples/23.txt

Lines changed: 32 additions & 0 deletions
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

src/bin/23.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
advent_of_code::solution!(23);
2+
3+
use advent_of_code::maneatingape::hash::*;
4+
5+
use std::collections::BTreeSet;
6+
7+
struct Computer {}
8+
9+
impl Computer {
10+
fn encode(name: &str) -> usize {
11+
let mut chars = name.chars();
12+
let first = chars.next().unwrap() as u8 - b'a';
13+
let second = chars.next().unwrap() as u8 - b'a';
14+
15+
first as usize * 26 + second as usize
16+
}
17+
18+
fn decode(id: usize) -> String {
19+
let first = (id / 26) as u8 + b'a';
20+
let second = (id % 26) as u8 + b'a';
21+
22+
format!("{}{}", first as char, second as char)
23+
}
24+
}
25+
26+
fn parse_data(input: &str) -> FastMap<usize, FastSet<usize>> {
27+
let mut nodes = FastMap::new();
28+
29+
for line in input.lines() {
30+
let left = Computer::encode(&line[0..2]);
31+
let right = Computer::encode(&line[3..5]);
32+
33+
nodes.entry(left).or_insert(FastSet::new()).insert(right);
34+
nodes.entry(right).or_insert(FastSet::new()).insert(left);
35+
}
36+
37+
nodes
38+
}
39+
40+
pub fn part_one(input: &str) -> Option<u32> {
41+
let nodes = parse_data(input);
42+
43+
let keys = nodes.keys().copied().collect::<Vec<_>>();
44+
45+
let mut result = 0;
46+
47+
let mut visited_t = FastSet::new();
48+
49+
// TODO: poglej samo sosede
50+
// TODO: spremeni hashmap-e v arraye (hitrejsi dostop)
51+
for computer_i in Computer::encode("ta")..=Computer::encode("tz") {
52+
if !nodes.contains_key(&computer_i) {
53+
continue;
54+
}
55+
56+
visited_t.insert(computer_i);
57+
58+
for (j, computer_j) in keys.iter().enumerate() {
59+
if visited_t.contains(computer_j) {
60+
continue;
61+
}
62+
63+
for computer_k in keys.iter().skip(j + 1) {
64+
if visited_t.contains(computer_k) {
65+
continue;
66+
}
67+
68+
if nodes[&computer_i].contains(computer_j)
69+
&& nodes[&computer_i].contains(computer_k)
70+
&& nodes[computer_j].contains(computer_k)
71+
{
72+
result += 1;
73+
}
74+
}
75+
}
76+
}
77+
78+
Some(result)
79+
}
80+
81+
pub fn part_two(input: &str) -> Option<String> {
82+
let nodes = parse_data(input);
83+
84+
let mut cache = FastSet::new();
85+
86+
let mut keys = nodes.keys().copied().collect::<Vec<_>>();
87+
keys.sort_by(|a, b| nodes[b].len().cmp(&nodes[a].len()));
88+
89+
let to_check = keys;
90+
let group = BTreeSet::new();
91+
let mut queue = vec![(to_check, group)];
92+
while let Some((c, g)) = queue.pop() {
93+
for i in 0..c.len() {
94+
let mut is_ok = true;
95+
for el in g.iter() {
96+
if !nodes[el].contains(&c[i]) {
97+
is_ok = false;
98+
break;
99+
}
100+
}
101+
102+
if is_ok {
103+
let mut new_g = g.clone();
104+
new_g.insert(c[i]);
105+
106+
if cache.contains(&new_g) {
107+
continue;
108+
}
109+
110+
cache.insert(new_g.clone());
111+
112+
let mut new_c = c.clone();
113+
new_c.remove(i);
114+
115+
queue.push((new_c, new_g));
116+
}
117+
}
118+
}
119+
120+
let mut result = cache
121+
.iter()
122+
.max_by(|x, y| x.len().cmp(&y.len()))
123+
.unwrap()
124+
.iter()
125+
.map(|&x| Computer::decode(x))
126+
.collect::<Vec<_>>();
127+
128+
result.sort_unstable();
129+
130+
let result = result.join(",");
131+
132+
Some(result)
133+
}
134+
135+
#[cfg(test)]
136+
mod tests {
137+
use super::*;
138+
139+
#[test]
140+
fn test_part_one() {
141+
let input = advent_of_code::template::read_file("examples", DAY);
142+
let result = part_one(&input);
143+
assert_eq!(result, Some(7));
144+
}
145+
146+
#[test]
147+
fn test_part_two() {
148+
let input = advent_of_code::template::read_file("examples", DAY);
149+
let result = part_two(&input);
150+
assert_eq!(result, Some(String::from("co,de,ka,ta")));
151+
}
152+
}

0 commit comments

Comments
 (0)