No performance improvement, but the code is a lot cleaner

This commit is contained in:
Connor Johnstone
2023-12-11 10:55:13 -07:00
parent c566b5bb64
commit 292171bf3e
6 changed files with 45 additions and 114 deletions

1
day_10/Cargo.lock generated
View File

@@ -205,7 +205,6 @@ dependencies = [
"ndarray",
"nom",
"num",
"rayon",
"strum",
"strum_macros",
]

View File

@@ -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"

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 7.7 MiB

Binary file not shown.

Binary file not shown.

View File

@@ -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::<Vec<_>>().len();
fn count_map(input: &str) -> Array2<usize> {
let rows = input.lines().count();
let columns = input.lines().next().unwrap().len();
let mut count_map: Array2<usize> = 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::<Vec<_>>();
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::<Vec<_>>().len();
let columns = input.lines().next().unwrap().len();
let mut count_map: Array2<usize> = 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();