diff --git a/Cargo.toml b/Cargo.toml index 030b756..d9c006d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] + + +[profile.release] +debug = true diff --git a/inputs/input.txt b/inputs/input.txt index b6997c3..101ce3a 100644 --- a/inputs/input.txt +++ b/inputs/input.txt @@ -1,10 +1,26 @@ -2682551651 -3223134263 -5848471412 -7438334862 -8731321573 -6415233574 -5564726843 -6683456445 -8582346112 -4617588236 +end-ry +jf-jb +jf-IO +jb-hz +jo-LM +hw-end +hw-LM +hz-ry +WI-start +LM-start +kd-jf +xi-WI +hw-jb +hz-jf +LM-jb +jb-xi +ry-jf +WI-jb +end-hz +jo-start +WI-jo +xi-ry +xi-LM +xi-hw +jo-xi +WI-jf diff --git a/inputs/sample.txt b/inputs/sample.txt index 03743f6..6fd8c41 100644 --- a/inputs/sample.txt +++ b/inputs/sample.txt @@ -1,10 +1,7 @@ -5483143223 -2745854711 -5264556173 -6141336146 -6357385478 -4167524645 -2176841721 -6882881134 -4846848554 -5283751526 +start-A +start-b +A-c +A-b +b-d +A-end +b-end diff --git a/src/main.rs b/src/main.rs index 738e685..0730c75 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,76 +6,66 @@ const INPUTS: [&'static str; 2] = [ include_str!("../inputs/input.txt"), ]; -fn parse_input(input: &'static str) -> Vec> { - input - .lines() - .map(|x| x.bytes().map(|x| (x - b'0') as u64).collect()) - .collect() -} +fn parse_input(input: &'static str) -> (Vec>, Vec) { + let mut map = HashMap::from([("start", 0), ("end", 1)]); + let mut cap_list = vec![false; 2]; + let mut adj_list = vec![vec![]; 2]; -fn solution(mut input: Vec>) -> u64 { - let m = input.len(); - let n = input[0].len(); - let mut step = 1; - - loop { - for row in input.iter_mut() { - for col in row { - if *col == 9 { - *col = 0; - } else { - *col += 1; - } - } - } - - let mut tmp = input.clone(); - - for i in 0..m { - for j in 0..n { - if input[i][j] == 0 { - dfs(&mut tmp, i as i32, j as i32); - } - } - } - input = tmp; - - if input.iter().all(|row| row.iter().all(|&c| c == 0)) { - return step; - } - step += 1; - } -} - -fn dfs(ip: &mut Vec>, i: i32, j: i32) { - for x in -1..=1 { - for y in -1..=1 { - if x == 0 && y == 0 { - continue; - } - let px = i + x; - let py = j + y; - - if px < 0 - || py < 0 - || px >= ip.len() as i32 - || py >= ip[0].len() as i32 - || ip[px as usize][py as usize] == 0 - { - continue; - } - - if ip[px as usize][py as usize] == 9 { - ip[px as usize][py as usize] = 0; + 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) { + v } else { - ip[px as usize][py as usize] += 1; - } + adj_list.push(vec![]); + cap_list.push(x.chars().any(char::is_uppercase)); + let i = map.len(); + map.insert(x, i); + i + }; - if ip[px as usize][py as usize] == 0 { - dfs(ip, px, py); - } + xi + }; + + let si = process(a); + let di = process(b); + + // Don't add mappings with destination start or source end + if di != 0 && si != 1 { + adj_list[si].push(di); + } + + if si != 0 && di != 1 { + adj_list[di].push(si); } } + + (adj_list, cap_list) +} + +use std::collections::HashMap; + +fn solution((adj_list, cap_list): (Vec>, Vec)) -> u64 { + let mut visited = vec![false; cap_list.len()]; + + dfs(&adj_list, &cap_list, &mut visited, 0) +} + +#[inline] +fn dfs(adj_list: &Vec>, cap_list: &[bool], visited: &mut Vec, node: usize) -> u64 { + if node == 1 { + return 1; + } + + 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; + } + } + + paths } fn main() { @@ -88,9 +78,9 @@ fn main() { #[bench] fn solution_bench(b: &mut test::Bencher) { + let input = parse_input(INPUTS[1]); b.iter(|| { - let input = parse_input(INPUTS[1]); - let result = solution(input); + let result = solution(input.clone()); test::black_box(result); }) }