diff --git a/src/tasks/day20.rs b/src/tasks/day20.rs index 0a251d7..c9f2060 100644 --- a/src/tasks/day20.rs +++ b/src/tasks/day20.rs @@ -2,13 +2,13 @@ use std::collections::{HashMap, HashSet, VecDeque}; pub fn run() { let input = std::fs::read_to_string("input/day20.txt").unwrap(); - let maze = Maze::from(&input, PortalField::create); + let maze = Maze::from(&input, PortalField::curried_factory); let part1 = maze.shortest_path(); println!("Part 1: {}", part1); } type C = i32; -type FieldFactory = fn(&MapPoint) -> Box; +type FieldFactory = Box Box>; #[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)] struct MapPoint { @@ -54,7 +54,7 @@ trait Field { fn neighbors(&self, at_level: usize) -> Vec; fn set_label_partner(&mut self, point: MapPoint); fn set_neighbors(&mut self, neighbors: Vec); - fn create(point: &MapPoint) -> Box where Self: Sized; + fn curried_factory(width: C, height: C) -> FieldFactory where Self: Sized; } struct PortalField { @@ -80,26 +80,45 @@ impl Field for PortalField { self.neighbors = neighbors; } - fn create(_: &MapPoint) -> Box where Self: Sized { - Box::new(PortalField::new()) + fn curried_factory(_: C, _: C) -> FieldFactory { + Box::new(|_| Box::new(PortalField::new())) } } -//impl Field for PortalField { -// fn neighbors(self, level: usize) -> Vec { -// if let Some((direction, p)) = self.dimension_neighbor { -// if direction == DimensionUp && level < 0 { -// let mut v = self.neighbors.clone(); -// v.push(p); -// v -// } else { -// self.neighbors.clone() -// } -// } else { -// self.neighbors.clone() -// } -// } -//} +struct DimensionField { + point: MapPoint, + neighbors: Vec, + jump: Option, + map_width: C, + map_height: C, +} + +impl DimensionField { + fn is_inner(&self) -> bool { + !self.is_outer() + } + fn is_outer(&self) -> bool { + false + } +} + +impl Field for DimensionField { + fn neighbors(&self, at_level: usize) -> Vec { + todo!() + } + + fn set_label_partner(&mut self, point: MapPoint) { + self.jump = Some(point); + } + + fn set_neighbors(&mut self, neighbors: Vec) { + self.neighbors = neighbors; + } + + fn curried_factory(width: C, height: C) -> FieldFactory { + Box::new(move |point: &MapPoint| Box::new(Self { point: *point, neighbors: vec![], jump: None, map_width: width, map_height: height })) + } +} type FieldMap = HashMap>; @@ -110,10 +129,10 @@ struct Maze { } impl Maze { - fn from(input: &String, field_factory: FieldFactory) -> Self { + fn from(input: &String, factory: fn(C, C) -> FieldFactory) -> Self { let (moc, width, height) = Self::map_of_chars(input); - let mut map = Self::create_map_of_free_spots(&moc, field_factory); + let mut map = Self::create_map_of_free_spots(&moc, factory(width, height)); Self::add_physical_neighbors(&mut map); let labels = Self::labels(&moc, width, height); Self::process_labels(&mut map, &labels); @@ -270,14 +289,14 @@ mod test { #[test] fn example1() { let input = std::fs::read_to_string("input/day20_example1.txt").unwrap(); - let maze = Maze::from(&input, PortalField::create); + let maze = Maze::from(&input, PortalField::curried_factory); assert_eq!(maze.shortest_path(), 23); } #[test] fn result() { let input = std::fs::read_to_string("input/day20.txt").unwrap(); - let maze = Maze::from(&input, PortalField::create); + let maze = Maze::from(&input, PortalField::curried_factory); assert_eq!(maze.shortest_path(), 454); } }