143 lines
3.6 KiB
Rust
143 lines
3.6 KiB
Rust
use super::Solution;
|
|
|
|
use hashbrown::HashSet;
|
|
|
|
pub struct Day10 {}
|
|
|
|
impl Solution for Day10 {
|
|
fn part1(
|
|
&self,
|
|
input: &mut Vec<String>,
|
|
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
|
|
let mut start = (0, 0);
|
|
let mut graph = input
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(r, line)| {
|
|
line.bytes()
|
|
.enumerate()
|
|
.map(|(c, tile)| {
|
|
if tile == b'S' {
|
|
start = (r, c);
|
|
}
|
|
self.connections(tile)
|
|
})
|
|
.collect::<Vec<_>>()
|
|
})
|
|
.collect::<Vec<_>>();
|
|
let pipe_loop = "J|-L7F"
|
|
.bytes()
|
|
.find_map(|start_tile| {
|
|
graph[start.0][start.1] = self.connections(start_tile);
|
|
self.find_loop(&graph, start)
|
|
})
|
|
.unwrap();
|
|
Ok(Box::new(pipe_loop.len() / 2))
|
|
}
|
|
|
|
fn part2(
|
|
&self,
|
|
_input: &mut Vec<String>,
|
|
) -> Result<Box<dyn std::fmt::Display + Sync>, Box<dyn std::error::Error>> {
|
|
Ok(Box::new("Ready"))
|
|
}
|
|
|
|
fn get_day(&self) -> u8 {
|
|
10
|
|
}
|
|
}
|
|
|
|
impl Day10 {
|
|
fn find_loop(
|
|
&self,
|
|
graph: &[Vec<[bool; 4]>],
|
|
start: (usize, usize),
|
|
) -> Option<HashSet<(usize, usize)>> {
|
|
let (mut r, mut c) = start;
|
|
let mut d = graph[r][c].iter().position(|&d| d).unwrap();
|
|
let mut seen = HashSet::new();
|
|
loop {
|
|
if !seen.insert((r, c)) {
|
|
break Some(seen);
|
|
}
|
|
let came_from = match d {
|
|
0 => {
|
|
r -= 1;
|
|
2
|
|
}
|
|
1 => {
|
|
c += 1;
|
|
3
|
|
}
|
|
2 => {
|
|
r += 1;
|
|
0
|
|
}
|
|
3 => {
|
|
c -= 1;
|
|
1
|
|
}
|
|
_ => unreachable!(),
|
|
};
|
|
if !graph[r][c][came_from] {
|
|
break None;
|
|
}
|
|
d = (0..4).find(|&i| i != came_from && graph[r][c][i]).unwrap();
|
|
}
|
|
}
|
|
|
|
fn connections(&self, tile: u8) -> [bool; 4] {
|
|
match tile {
|
|
// [ up, right, down, left]
|
|
b'|' => [true, false, true, false],
|
|
b'-' => [false, true, false, true],
|
|
b'L' => [true, true, false, false],
|
|
b'J' => [true, false, false, true],
|
|
b'7' => [false, false, true, true],
|
|
b'F' => [false, true, true, false],
|
|
_ => [false, false, false, false],
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Test from puzzle input
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
use crate::*;
|
|
|
|
#[test]
|
|
fn part1() {
|
|
let challenge = day10::Day10 {};
|
|
|
|
//Complete the Challenge
|
|
let answer = challenge
|
|
.part1(
|
|
utils::get_input(challenge.get_day(), utils::InputType::Test1)
|
|
.unwrap()
|
|
.as_mut(),
|
|
)
|
|
.unwrap()
|
|
.to_string();
|
|
|
|
assert_eq!(answer, "Ready");
|
|
}
|
|
|
|
#[test]
|
|
fn part2() {
|
|
let challenge = day10::Day10 {};
|
|
|
|
//Complete the Challenge
|
|
let answer = challenge
|
|
.part2(
|
|
utils::get_input(challenge.get_day(), utils::InputType::Test2)
|
|
.unwrap()
|
|
.as_mut(),
|
|
)
|
|
.unwrap()
|
|
.to_string();
|
|
|
|
assert_eq!(answer, "Ready");
|
|
}
|
|
}
|