day20 refactored for part 2 - currying
This commit is contained in:
@@ -2,13 +2,13 @@ use std::collections::{HashMap, HashSet, VecDeque};
|
|||||||
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let input = std::fs::read_to_string("input/day20.txt").unwrap();
|
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();
|
let part1 = maze.shortest_path();
|
||||||
println!("Part 1: {}", part1);
|
println!("Part 1: {}", part1);
|
||||||
}
|
}
|
||||||
|
|
||||||
type C = i32;
|
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)]
|
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
|
||||||
struct MapPoint {
|
struct MapPoint {
|
||||||
@@ -54,7 +54,7 @@ trait Field {
|
|||||||
fn neighbors(&self, at_level: usize) -> Vec<RealPoint>;
|
fn neighbors(&self, at_level: usize) -> Vec<RealPoint>;
|
||||||
fn set_label_partner(&mut self, point: MapPoint);
|
fn set_label_partner(&mut self, point: MapPoint);
|
||||||
fn set_neighbors(&mut self, neighbors: Vec<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 {
|
struct PortalField {
|
||||||
@@ -80,26 +80,45 @@ impl Field for PortalField {
|
|||||||
self.neighbors = neighbors;
|
self.neighbors = neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create(_: &MapPoint) -> Box<dyn Field> where Self: Sized {
|
fn curried_factory(_: C, _: C) -> FieldFactory {
|
||||||
Box::new(PortalField::new())
|
Box::new(|_| Box::new(PortalField::new()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl Field for PortalField {
|
struct DimensionField {
|
||||||
// fn neighbors(self, level: usize) -> Vec<Point> {
|
point: MapPoint,
|
||||||
// if let Some((direction, p)) = self.dimension_neighbor {
|
neighbors: Vec<MapPoint>,
|
||||||
// if direction == DimensionUp && level < 0 {
|
jump: Option<MapPoint>,
|
||||||
// let mut v = self.neighbors.clone();
|
map_width: C,
|
||||||
// v.push(p);
|
map_height: C,
|
||||||
// v
|
}
|
||||||
// } else {
|
|
||||||
// self.neighbors.clone()
|
impl DimensionField {
|
||||||
// }
|
fn is_inner(&self) -> bool {
|
||||||
// } else {
|
!self.is_outer()
|
||||||
// self.neighbors.clone()
|
}
|
||||||
// }
|
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>>;
|
type FieldMap = HashMap<MapPoint, Box<dyn Field>>;
|
||||||
|
|
||||||
@@ -110,10 +129,10 @@ struct Maze {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 (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);
|
Self::add_physical_neighbors(&mut map);
|
||||||
let labels = Self::labels(&moc, width, height);
|
let labels = Self::labels(&moc, width, height);
|
||||||
Self::process_labels(&mut map, &labels);
|
Self::process_labels(&mut map, &labels);
|
||||||
@@ -270,14 +289,14 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn example1() {
|
fn example1() {
|
||||||
let input = std::fs::read_to_string("input/day20_example1.txt").unwrap();
|
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);
|
assert_eq!(maze.shortest_path(), 23);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn result() {
|
fn result() {
|
||||||
let input = std::fs::read_to_string("input/day20.txt").unwrap();
|
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);
|
assert_eq!(maze.shortest_path(), 454);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user