Modest performance improvement. Need to switch from column search to row search
This commit is contained in:
@@ -1,9 +1,3 @@
|
||||
// use nom::{
|
||||
// character::complete,
|
||||
// multi::separated_list1,
|
||||
// IResult,
|
||||
// };
|
||||
use std::collections::HashMap;
|
||||
use ndarray::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -12,24 +6,7 @@ struct Point {
|
||||
y: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Direction {
|
||||
North,
|
||||
South,
|
||||
East,
|
||||
West,
|
||||
}
|
||||
|
||||
pub fn part1(input: &str) -> String {
|
||||
let node_mapping = HashMap::from([
|
||||
('|', Some([Direction::North, Direction::South])),
|
||||
('-', Some([Direction::East, Direction::West])),
|
||||
('L', Some([Direction::North, Direction::East])),
|
||||
('J', Some([Direction::North, Direction::West])),
|
||||
('7', Some([Direction::South, Direction::West])),
|
||||
('F', Some([Direction::South, Direction::East])),
|
||||
('.', None),
|
||||
]);
|
||||
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()];
|
||||
@@ -66,20 +43,20 @@ pub fn part1(input: &str) -> String {
|
||||
next_nodes.push(Point{x: point.x-1, y: point.y});
|
||||
}
|
||||
}
|
||||
} else if let Some(dirs) = node_mapping.get(&character).unwrap() {
|
||||
if dirs.contains(&Direction::North) && point.y != 0 {
|
||||
} else {
|
||||
if ['|', 'L', 'J'].contains(&character) && point.y != 0 {
|
||||
next_nodes.push(Point{x: point.x, y: point.y-1});
|
||||
}
|
||||
if dirs.contains(&Direction::East) && point.x != columns-1 {
|
||||
if ['-', 'F', 'L'].contains(&character) && point.x != columns-1 {
|
||||
next_nodes.push(Point{x: point.x+1, y: point.y});
|
||||
}
|
||||
if dirs.contains(&Direction::South) && point.y != rows-1 {
|
||||
if ['|', '7', 'F'].contains(&character) && point.y != rows-1 {
|
||||
next_nodes.push(Point{x: point.x, y: point.y+1});
|
||||
}
|
||||
if dirs.contains(&Direction::West) && point.x != 0 {
|
||||
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![];
|
||||
@@ -94,15 +71,6 @@ pub fn part1(input: &str) -> String {
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> String {
|
||||
let node_mapping = HashMap::from([
|
||||
('|', Some([Direction::North, Direction::South])),
|
||||
('-', Some([Direction::East, Direction::West])),
|
||||
('L', Some([Direction::North, Direction::East])),
|
||||
('J', Some([Direction::North, Direction::West])),
|
||||
('7', Some([Direction::South, Direction::West])),
|
||||
('F', Some([Direction::South, Direction::East])),
|
||||
('.', None),
|
||||
]);
|
||||
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()];
|
||||
@@ -139,20 +107,20 @@ pub fn part2(input: &str) -> String {
|
||||
next_nodes.push(Point{x: point.x-1, y: point.y});
|
||||
}
|
||||
}
|
||||
} else if let Some(dirs) = node_mapping.get(&character).unwrap() {
|
||||
if dirs.contains(&Direction::North) && point.y != 0 {
|
||||
} else {
|
||||
if ['|', 'L', 'J'].contains(&character) && point.y != 0 {
|
||||
next_nodes.push(Point{x: point.x, y: point.y-1});
|
||||
}
|
||||
if dirs.contains(&Direction::East) && point.x != columns-1 {
|
||||
if ['-', 'F', 'L'].contains(&character) && point.x != columns-1 {
|
||||
next_nodes.push(Point{x: point.x+1, y: point.y});
|
||||
}
|
||||
if dirs.contains(&Direction::South) && point.y != rows-1 {
|
||||
if ['|', '7', 'F'].contains(&character) && point.y != rows-1 {
|
||||
next_nodes.push(Point{x: point.x, y: point.y+1});
|
||||
}
|
||||
if dirs.contains(&Direction::West) && point.x != 0 {
|
||||
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![];
|
||||
@@ -174,31 +142,27 @@ pub fn part2(input: &str) -> String {
|
||||
// Now we go in one direction
|
||||
let mut sum = 0.0_f32;
|
||||
let mut count_f = 0_i32;
|
||||
let mut count_l = 0_i32;
|
||||
let mut count_7 = 0_i32;
|
||||
let mut count_j = 0_i32;
|
||||
for new_y in (0..y).rev() {
|
||||
// And we keep moving in that direction
|
||||
// If we reach a part of the pipe
|
||||
// L's cancel F's, J's cancel 7's
|
||||
if count_map[[new_y,x]] != 0 {
|
||||
// We can add either a half or full count
|
||||
let next_character = input.lines().nth(new_y).unwrap().chars().nth(x).unwrap();
|
||||
if ['7', 'S'].contains(&next_character) {
|
||||
count_7 += 1;
|
||||
} else if next_character == 'J' {
|
||||
count_j += 1;
|
||||
count_7 -= 1;
|
||||
} else if next_character == 'L' {
|
||||
count_l += 1;
|
||||
count_f -= 1;
|
||||
} else if next_character == 'F' {
|
||||
count_f += 1;
|
||||
} else if next_character == '-' {
|
||||
sum += 1.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
count_f = (count_f - count_l).abs(); // L's cancel with F
|
||||
count_7 = (count_7 - count_j).abs(); // J's cancel with 7
|
||||
count_f = count_f.abs();
|
||||
count_7 = count_7.abs();
|
||||
sum += (count_f + count_7) as f32 / 2.0;
|
||||
if sum % 2.0 != 0.0 {
|
||||
inside_points += 1;
|
||||
|
||||
Reference in New Issue
Block a user