Naive day 8 added.

This commit is contained in:
Dennis Brentjes
2023-12-11 14:42:36 +01:00
parent 3b529af1d6
commit c2722a35fc
4 changed files with 898 additions and 1 deletions

139
src/days/day8.rs Normal file
View File

@@ -0,0 +1,139 @@
use std::{path::Path, str::FromStr, collections::HashMap};
use itertools::Itertools;
use crate::{error::AdventError, input::read_into};
#[derive(Clone, Debug)]
enum Direction {
Left,
Right,
}
impl FromStr for Direction {
type Err = AdventError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"L" => Ok(Direction::Left),
"R" => Ok(Direction::Right),
_ => Err(AdventError(format!("Unexpected input for Direction: {}", s))),
}
}
}
#[derive(Clone, Debug)]
struct Node {
left: String,
right: String
}
struct BaseMap {
catalog: HashMap<String, Node>,
directions: Vec<Direction>,
start: Vec<String>,
}
trait Step {
fn take_step(&self, current: &String, direction: &Direction) -> Result<String, AdventError>;
}
impl Step for BaseMap {
fn take_step(&self, current: &String, direction: &Direction) -> Result<String, AdventError> {
if let Some(node) = self.catalog.get(current) {
Ok(match direction {
Direction::Left => node.left.clone(),
Direction::Right => node.right.clone()
})
}
else {
Err(AdventError(format!("Node missing in catalog for: {}", current)))
}
}
}
struct Map1(BaseMap);
struct Map2(BaseMap);
impl FromStr for BaseMap {
type Err = AdventError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut lines = s.lines();
let directions = &lines.next().unwrap().chars().map(|c| {
Ok(Direction::from_str(format!("{}", c).as_str())?)
}).collect::<Result<Vec<Direction>, AdventError>>()?;
let mut nodes = HashMap::<String, Node>::new();
for line in lines.skip(1) {
let name = &line[0..3];
let left = &line[7..10];
let right = &line[12..15];
nodes.insert(name.to_string(), Node{left: left.to_string(), right: right.to_string()});
};
Ok(BaseMap{
catalog: nodes,
directions: directions.to_vec(),
start: vec![]
})
}
}
impl FromStr for Map1 {
type Err = AdventError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut base_map = BaseMap::from_str(s)?;
base_map.start.push("AAA".to_string());
Ok(Map1(base_map))
}
}
impl FromStr for Map2 {
type Err = AdventError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut base_map = BaseMap::from_str(s)?;
base_map.start = base_map.catalog.keys().filter(|x| x.ends_with('A')).map(|x| x.clone()).collect_vec();
Ok(Map2(base_map))
}
}
fn is_end1(node: &String) -> bool {
node == &"ZZZ".to_string()
}
fn is_end2(nodes: &Vec<String>) -> bool {
nodes.iter().all(|x| {
x.ends_with('Z')
})
}
pub fn one() -> Result<u32, AdventError> {
let map = read_into::<Map1>(Path::new("resources/input8.txt"))?.0;
let mut node = map.start[0].clone();
for (i, direction) in map.directions.iter().cycle().enumerate() {
node = map.take_step(&node, direction)?;
if is_end1(&node) {
return Ok(i as u32 +1);
}
}
panic!("Cycle iterator should never terminate")
}
pub fn two() -> Result<u32, AdventError> {
let map = read_into::<Map2>(Path::new("resources/input8.txt"))?.0;
let mut nodes = map.start.clone();
for (i, direction) in map.directions.iter().cycle().enumerate() {
nodes = nodes.iter().map(|current| {
map.take_step(&current, direction)
}).collect::<Result<Vec<String>,AdventError>>()?.iter().unique().map(|x| x.clone()).collect_vec();
if is_end2(&nodes) {
return Ok(i as u32 +1);
}
}
panic!("Cycle iterator should never terminate")
}

View File

@@ -4,4 +4,5 @@ pub mod day3;
pub mod day4;
pub mod day5;
pub mod day6;
pub mod day7;
pub mod day7;
pub mod day8;

View File

@@ -18,6 +18,7 @@ fn main() -> Result<(), AdventError> {
(day5::one as fn() -> Result<u32, AdventError>, day5::two as fn() -> Result<u32, AdventError>),
(day6::one as fn() -> Result<u32, AdventError>, day6::two as fn() -> Result<u32, AdventError>),
(day7::one as fn() -> Result<u32, AdventError>, day7::two as fn() -> Result<u32, AdventError>),
(day8::one as fn() -> Result<u32, AdventError>, day8::two as fn() -> Result<u32, AdventError>),
];
if env::args().len() == 1 {