day20 refactored for part 2 - currying
This commit is contained in:
@@ -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<dyn Field>;
|
||||
type FieldFactory = Box<dyn Fn(&MapPoint) -> Box<dyn Field>>;
|
||||
|
||||
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
|
||||
struct MapPoint {
|
||||
@@ -54,7 +54,7 @@ trait Field {
|
||||
fn neighbors(&self, at_level: usize) -> Vec<RealPoint>;
|
||||
fn set_label_partner(&mut self, point: MapPoint);
|
||||
fn set_neighbors(&mut self, neighbors: Vec<MapPoint>);
|
||||
fn create(point: &MapPoint) -> Box<dyn Field> 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<dyn Field> 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<Point> {
|
||||
// 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<MapPoint>,
|
||||
jump: Option<MapPoint>,
|
||||
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<RealPoint> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn set_label_partner(&mut self, point: MapPoint) {
|
||||
self.jump = Some(point);
|
||||
}
|
||||
|
||||
fn set_neighbors(&mut self, neighbors: Vec<MapPoint>) {
|
||||
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<MapPoint, Box<dyn Field>>;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user