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