1
0
Fork 0

Added Day 12 Part 2

master 12.2
Ishan Jain 1 year ago
parent 66a4e0794d
commit 9a03703bac

@ -13,7 +13,7 @@ fn parse_input(input: &'static str) -> (Vec<Vec<usize>>, Vec<bool>) {
for (a, b) in input.lines().map(|x| x.split_once('-')).flatten() {
let mut process = |x: &'static str| -> usize {
let xi = if let Some(&v) = map.get(x) {
if let Some(&v) = map.get(x) {
v
} else {
adj_list.push(vec![]);
@ -21,9 +21,7 @@ fn parse_input(input: &'static str) -> (Vec<Vec<usize>>, Vec<bool>) {
let i = map.len();
map.insert(x, i);
i
};
xi
}
};
let si = process(a);
@ -33,7 +31,6 @@ fn parse_input(input: &'static str) -> (Vec<Vec<usize>>, Vec<bool>) {
if di != 0 && si != 1 {
adj_list[si].push(di);
}
if si != 0 && di != 1 {
adj_list[di].push(si);
}
@ -45,26 +42,47 @@ fn parse_input(input: &'static str) -> (Vec<Vec<usize>>, Vec<bool>) {
use std::collections::HashMap;
fn solution((adj_list, cap_list): (Vec<Vec<usize>>, Vec<bool>)) -> u64 {
let mut visited = vec![false; cap_list.len()];
let mut visited = 0;
let mut memo = HashMap::new();
dfs(&adj_list, &cap_list, &mut visited, 0)
dfs::<true>(&adj_list, &cap_list, &mut visited, &mut memo, 0)
}
#[inline]
fn dfs(adj_list: &Vec<Vec<usize>>, cap_list: &[bool], visited: &mut Vec<bool>, node: usize) -> u64 {
fn dfs<const REPEAT: bool>(
adj_list: &Vec<Vec<usize>>,
cap_list: &[bool],
visited: &mut u64,
map: &mut HashMap<(usize, bool, u64), u64>,
node: usize,
) -> u64 {
if node == 1 {
return 1;
}
if let Some(&v) = map.get(&(node, REPEAT, *visited)) {
return v;
}
let mut paths = 0;
for &neighbour in adj_list[node].iter() {
if !visited[neighbour] || cap_list[neighbour] {
visited[neighbour] = true;
paths += dfs(adj_list, cap_list, visited, neighbour);
visited[neighbour] = false;
match ((*visited & (1 << neighbour) > 0), (cap_list[neighbour])) {
(false, _) | (_, true) => {
*visited |= 1 << neighbour;
paths += dfs::<REPEAT>(adj_list, cap_list, visited, map, neighbour);
*visited &= !(1 << neighbour);
}
// If repeat flag is set, We include the node once more and calculate all paths
(true, false) if REPEAT => {
paths += dfs::<false>(adj_list, cap_list, visited, map, neighbour);
}
_ => (),
}
}
map.insert((node, REPEAT, *visited), paths);
paths
}

Loading…
Cancel
Save