diff --git a/day_10/Cargo.lock b/day_10/Cargo.lock index 315cf08..fb28326 100644 --- a/day_10/Cargo.lock +++ b/day_10/Cargo.lock @@ -205,7 +205,6 @@ dependencies = [ "ndarray", "nom", "num", - "rayon", "strum", "strum_macros", ] diff --git a/day_10/Cargo.toml b/day_10/Cargo.toml index b820928..bb1da07 100644 --- a/day_10/Cargo.toml +++ b/day_10/Cargo.toml @@ -10,7 +10,6 @@ csv = "1.3.0" ndarray = "0.15.6" nom = "7.1.3" num = "0.4.1" -rayon = "1.8.0" strum = "0.25.0" strum_macros = "0.25.3" diff --git a/day_10/flamegraph.svg b/day_10/flamegraph.svg index 110744d..e134f65 100644 --- a/day_10/flamegraph.svg +++ b/day_10/flamegraph.svg @@ -1,4 +1,4 @@ - \ No newline at end of file diff --git a/day_10/perf.data b/day_10/perf.data index 074e589..299989f 100644 Binary files a/day_10/perf.data and b/day_10/perf.data differ diff --git a/day_10/perf.data.old b/day_10/perf.data.old index d2c7259..da5da5f 100644 Binary files a/day_10/perf.data.old and b/day_10/perf.data.old differ diff --git a/day_10/src/lib.rs b/day_10/src/lib.rs index 1aa1e3c..839cfe1 100644 --- a/day_10/src/lib.rs +++ b/day_10/src/lib.rs @@ -6,131 +6,64 @@ struct Point { y: usize, } -pub fn part1(input: &str) -> String { - let mut current_nodes = vec![input.lines().enumerate().find_map(|(y,line)| { - line.chars().position(|character| {character == 'S'}).and_then(|x| {Some(Point{x, y})}) - }).unwrap()]; - let rows = input.lines().collect::>().len(); +fn count_map(input: &str) -> Array2 { + let rows = input.lines().count(); let columns = input.lines().next().unwrap().len(); let mut count_map: Array2 = Array::zeros((rows, columns)); - let mut num_steps = 0; + + let s_point = input.lines().enumerate().find_map(|(y,line)| { + line.chars().position(|character| {character == 'S'}).and_then(|x| {Some(Point{x, y})}) + }).unwrap(); + let initial_directions = [ + (['|','7','F'], (0_i32, -1_i32), s_point.y > 0), + (['-','7','J'], (1_i32, 0_i32), s_point.x < columns), + (['|','L','J'], (0_i32, 1_i32), s_point.y < rows), + (['-','F','L'], (-1_i32, 0_i32), s_point.x > 0), + ]; + let mut current_nodes = initial_directions.into_iter().filter_map(|(characters, (x, y), condition)| { + condition.then(|| { + let next_character = input.as_bytes()[((s_point.y as i32 + y)*(columns as i32+1) + s_point.x as i32 + x) as usize] as char; + characters.contains(&next_character).then_some(Point{x: (s_point.x as i32 + x) as usize, y: (s_point.y as i32 + y) as usize}) + }) + }).flatten().collect::>(); + + let mut num_steps = 1; while current_nodes.len() > 0 { let mut next_nodes = vec![]; current_nodes.iter().for_each(|point| { let character = input.lines().nth(point.y).unwrap().chars().nth(point.x).unwrap(); - if character == 'S' { - if point.y != 0 { - let next_character = input.lines().nth(point.y-1).unwrap().chars().nth(point.x).unwrap(); - if ['|','7','F'].contains(&next_character) { - next_nodes.push(Point{x: point.x, y: point.y-1}); - } - } - if point.x != columns-1 { - let next_character = input.lines().nth(point.y).unwrap().chars().nth(point.x+1).unwrap(); - if ['-','7','J'].contains(&next_character) { - next_nodes.push(Point{x: point.x+1, y: point.y}); - } - } - if point.y != rows-1 { - let next_character = input.lines().nth(point.y+1).unwrap().chars().nth(point.x).unwrap(); - if ['|','L','J'].contains(&next_character) { - next_nodes.push(Point{x: point.x, y: point.y+1}); - } - } - if point.x != 0 { - let next_character = input.lines().nth(point.y).unwrap().chars().nth(point.x-1).unwrap(); - if ['-','F','L'].contains(&next_character) { - next_nodes.push(Point{x: point.x-1, y: point.y}); - } - } - } else { - if ['|', 'L', 'J'].contains(&character) && point.y != 0 { - next_nodes.push(Point{x: point.x, y: point.y-1}); - } - if ['-', 'F', 'L'].contains(&character) && point.x != columns-1 { - next_nodes.push(Point{x: point.x+1, y: point.y}); - } - if ['|', '7', 'F'].contains(&character) && point.y != rows-1 { - next_nodes.push(Point{x: point.x, y: point.y+1}); - } - if ['-', 'J', '7'].contains(&character) && point.x != 0 { - next_nodes.push(Point{x: point.x-1, y: point.y}); - } + if ['|', 'L', 'J'].contains(&character) && point.y != 0 { + next_nodes.push(Point{x: point.x, y: point.y-1}); + } + if ['-', 'F', 'L'].contains(&character) && point.x != columns-1 { + next_nodes.push(Point{x: point.x+1, y: point.y}); + } + if ['|', '7', 'F'].contains(&character) && point.y != rows-1 { + next_nodes.push(Point{x: point.x, y: point.y+1}); + } + if ['-', 'J', '7'].contains(&character) && point.x != 0 { + next_nodes.push(Point{x: point.x-1, y: point.y}); } }); num_steps += 1; - current_nodes = vec![]; - next_nodes.iter().for_each(|point| { - if count_map[[point.y, point.x]] == 0 { + current_nodes = next_nodes.iter().filter_map(|point| { + (count_map[[point.y, point.x]] == 0).then(|| { count_map[[point.y, point.x]] = num_steps; - current_nodes.push(Point{x: point.x, y: point.y}); - } - }); + Point{x: point.x, y: point.y} + }) + }).collect(); } + count_map +} + +pub fn part1(input: &str) -> String { + let count_map = count_map(input); count_map.iter().max().unwrap().to_string() } pub fn part2(input: &str) -> String { - let mut current_nodes = vec![input.lines().enumerate().find_map(|(y,line)| { - line.chars().position(|character| {character == 'S'}).and_then(|x| {Some(Point{x, y})}) - }).unwrap()]; - let rows = input.lines().collect::>().len(); - let columns = input.lines().next().unwrap().len(); - let mut count_map: Array2 = Array::zeros((rows, columns)); - let mut num_steps = 0; - while current_nodes.len() > 0 { - let mut next_nodes = vec![]; - current_nodes.iter().for_each(|point| { - let character = input.lines().nth(point.y).unwrap().chars().nth(point.x).unwrap(); - if character == 'S' { - if point.y != 0 { - let next_character = input.lines().nth(point.y-1).unwrap().chars().nth(point.x).unwrap(); - if ['|','7','F'].contains(&next_character) { - next_nodes.push(Point{x: point.x, y: point.y-1}); - } - } - if point.x != columns-1 { - let next_character = input.lines().nth(point.y).unwrap().chars().nth(point.x+1).unwrap(); - if ['-','7','J'].contains(&next_character) { - next_nodes.push(Point{x: point.x+1, y: point.y}); - } - } - if point.y != rows-1 { - let next_character = input.lines().nth(point.y+1).unwrap().chars().nth(point.x).unwrap(); - if ['|','L','J'].contains(&next_character) { - next_nodes.push(Point{x: point.x, y: point.y+1}); - } - } - if point.x != 0 { - let next_character = input.lines().nth(point.y).unwrap().chars().nth(point.x-1).unwrap(); - if ['-','F','L'].contains(&next_character) { - next_nodes.push(Point{x: point.x-1, y: point.y}); - } - } - } else { - if ['|', 'L', 'J'].contains(&character) && point.y != 0 { - next_nodes.push(Point{x: point.x, y: point.y-1}); - } - if ['-', 'F', 'L'].contains(&character) && point.x != columns-1 { - next_nodes.push(Point{x: point.x+1, y: point.y}); - } - if ['|', '7', 'F'].contains(&character) && point.y != rows-1 { - next_nodes.push(Point{x: point.x, y: point.y+1}); - } - if ['-', 'J', '7'].contains(&character) && point.x != 0 { - next_nodes.push(Point{x: point.x-1, y: point.y}); - } - } - }); - num_steps += 1; - current_nodes = vec![]; - next_nodes.iter().for_each(|point| { - if count_map[[point.y, point.x]] == 0 { - count_map[[point.y, point.x]] = num_steps; - current_nodes.push(Point{x: point.x, y: point.y}); - } - }); - } + let mut count_map = count_map(input); + let &[rows, columns] = count_map.shape() else { panic!() }; let s_position = input.lines().enumerate().find_map(|(y,line)| { line.chars().position(|character| {character == 'S'}).and_then(|x| {Some(Point{x, y})}) }).unwrap();