Day 10 part 2
This commit is contained in:
parent
c8d4d12648
commit
cb2d876e94
1 changed files with 120 additions and 22 deletions
142
src/bin/day10.rs
142
src/bin/day10.rs
|
@ -2,7 +2,7 @@ use aoc23::prelude::*;
|
||||||
use derive_builder::Builder;
|
use derive_builder::Builder;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::{str::FromStr, time::Instant};
|
use std::{collections::HashSet, str::FromStr, time::Instant};
|
||||||
|
|
||||||
static DAY: u8 = 10;
|
static DAY: u8 = 10;
|
||||||
|
|
||||||
|
@ -18,12 +18,26 @@ enum PipeDirection {
|
||||||
Ground,
|
Ground,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PipeDirection {
|
||||||
|
fn is_north(&self) -> bool {
|
||||||
|
matches!(self, PipeDirection::NorthEast | PipeDirection::NorthWest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Pipe {
|
struct Pipe {
|
||||||
position: (usize, usize),
|
position: (usize, usize),
|
||||||
direction: PipeDirection,
|
direction: PipeDirection,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Eq for Pipe {}
|
||||||
|
|
||||||
|
impl PartialEq for Pipe {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.position == other.position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Pipe {
|
impl Pipe {
|
||||||
fn for_char(c: char, position: (usize, usize)) -> Self {
|
fn for_char(c: char, position: (usize, usize)) -> Self {
|
||||||
match c {
|
match c {
|
||||||
|
@ -230,25 +244,85 @@ fn part2(input: String) -> Result<usize> {
|
||||||
|
|
||||||
// algo
|
// algo
|
||||||
let a_start = Instant::now();
|
let a_start = Instant::now();
|
||||||
let mut path = vec![];
|
let mut path = vec![
|
||||||
|
&pipes.start,
|
||||||
|
pipes
|
||||||
|
.start
|
||||||
|
.connects_to()
|
||||||
|
.into_iter()
|
||||||
|
.next()
|
||||||
|
.map(|pos| pipes.get(&pos))
|
||||||
|
.unwrap(),
|
||||||
|
];
|
||||||
loop {
|
loop {
|
||||||
// reached end
|
let previous = path.get(path.len() - 2).unwrap();
|
||||||
if paths[0].1.position.0 == paths[1].1.position.0
|
let next = path
|
||||||
&& paths[0].1.position.1 == paths[1].1.position.1
|
.last()
|
||||||
{
|
.unwrap()
|
||||||
break;
|
.connects_to()
|
||||||
}
|
.into_iter()
|
||||||
answer += 1;
|
.filter(|pipe| pipe.0 != previous.position.0 || pipe.1 != previous.position.1)
|
||||||
for path in paths.iter_mut() {
|
.next()
|
||||||
let next = path
|
.map(|pos| pipes.get(&pos))
|
||||||
.1
|
.unwrap();
|
||||||
.connects_to()
|
match next.direction {
|
||||||
.into_iter()
|
PipeDirection::Start => {
|
||||||
.filter(|pipe| pipe.0 != path.0.position.0 || pipe.1 != path.0.position.1)
|
break;
|
||||||
.next()
|
}
|
||||||
.map(|pos| pipes.get(&pos))
|
_ => {
|
||||||
.unwrap();
|
path.push(next);
|
||||||
*path = (path.1, next);
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let mut answer = 0;
|
||||||
|
for (ri, row) in pipes.grid.iter().enumerate() {
|
||||||
|
for (idx, pipe) in row.iter().enumerate() {
|
||||||
|
if !path.contains(&pipe) {
|
||||||
|
// println!("Pipe check, {}, {}", ri, idx);
|
||||||
|
let (intersections, _) = row
|
||||||
|
.iter()
|
||||||
|
// Start at current non path pipe we are checking
|
||||||
|
.skip(idx + 1)
|
||||||
|
// Add fake pipe at the end so we can match on pipes on the right edge of the Grid
|
||||||
|
// .chain(std::iter::once(&Pipe { position: (0, 0), direction:
|
||||||
|
// PipeDirection::Ground, }))
|
||||||
|
.fold(
|
||||||
|
(0, None),
|
||||||
|
|(i_count, intersecting_dir): (usize, Option<&PipeDirection>), pipe| {
|
||||||
|
if path.contains(&pipe) {
|
||||||
|
return match pipe.direction {
|
||||||
|
PipeDirection::Vertical => (i_count + 1, None),
|
||||||
|
PipeDirection::NorthWest
|
||||||
|
| PipeDirection::NorthEast
|
||||||
|
| PipeDirection::SouthEast
|
||||||
|
| PipeDirection::SouthWest => match intersecting_dir {
|
||||||
|
Some(last_direction) => {
|
||||||
|
match (
|
||||||
|
last_direction.is_north(),
|
||||||
|
pipe.direction.is_north(),
|
||||||
|
) {
|
||||||
|
(true, true) | (false, false) => (i_count, None),
|
||||||
|
(true, false) | (false, true) => {
|
||||||
|
(i_count + 1, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => (i_count, Some(&pipe.direction)),
|
||||||
|
},
|
||||||
|
PipeDirection::Horizontal => (i_count, intersecting_dir),
|
||||||
|
_ => (i_count, None),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return (i_count, None);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// println!( "\t\tPipe check, {}, {} intersections: {} | {}", ri, idx,
|
||||||
|
// intersections, (intersections > 0 && intersections % 2 == 1) );
|
||||||
|
if intersections > 0 && intersections % 2 == 1 {
|
||||||
|
answer += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let algo_time = a_start.elapsed();
|
let algo_time = a_start.elapsed();
|
||||||
|
@ -266,8 +340,7 @@ async fn main() -> Result<()> {
|
||||||
println!("=====");
|
println!("=====");
|
||||||
let input = utils::aoc::get_puzzle_input(DAY).await?;
|
let input = utils::aoc::get_puzzle_input(DAY).await?;
|
||||||
part1(input.clone())?;
|
part1(input.clone())?;
|
||||||
|
part2(input.clone())?;
|
||||||
// part2(input.clone())?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +365,27 @@ LJ..."
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_2() -> Result<()> {
|
fn test_part_2_small() -> Result<()> {
|
||||||
|
assert_eq!(
|
||||||
|
part2(
|
||||||
|
"...........
|
||||||
|
.S-------7.
|
||||||
|
.|F-----7|.
|
||||||
|
.||.....||.
|
||||||
|
.||.....||.
|
||||||
|
.|L-7.F-J|.
|
||||||
|
.|..|.|..|.
|
||||||
|
.L--J.L--J.
|
||||||
|
..........."
|
||||||
|
.to_owned(),
|
||||||
|
)?,
|
||||||
|
4
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_2_med() -> Result<()> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
part2(
|
part2(
|
||||||
".F----7F7F7F7F-7....
|
".F----7F7F7F7F-7....
|
||||||
|
@ -309,6 +402,11 @@ L--J.L7...LJS7F-7L7.
|
||||||
)?,
|
)?,
|
||||||
8
|
8
|
||||||
);
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part_2_hard() -> Result<()> {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
part2(
|
part2(
|
||||||
"FF7FSF7F7F7F7F7F---7
|
"FF7FSF7F7F7F7F7F---7
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue