Files
AdventOfCode2023/src/solutions/day10.rs
T
2023-12-10 23:21:24 +00:00

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");
}
}