Compare commits

...

9 Commits

Author SHA1 Message Date
79ea3c29d0 day20 format 2022-10-02 17:49:00 +02:00
e87d31c941 day20 cleanup 2022-10-02 17:48:35 +02:00
6e06599c33 day20 part 2 2022-10-02 17:46:33 +02:00
3b829649f3 day20 refactored for part 2 - currying 2022-10-02 16:54:45 +02:00
922f2a483c day20 refactored for part 2 2022-10-02 14:17:08 +02:00
4002297ede day20 refactored for part 2 2022-10-02 14:05:24 +02:00
9a34cca688 day20 part 1 2022-10-02 13:19:36 +02:00
358e185501 day20 shortest path to come 2022-10-02 11:28:33 +02:00
eeda13a0d6 day19 format 2022-10-02 11:06:40 +02:00
7 changed files with 545 additions and 14 deletions

109
input/day20.txt Normal file
View File

@@ -0,0 +1,109 @@
V W A S Q A K
D V A H R Y N
#################################.#########.###.#.###.#########.#####.#################################
#...........#.#...#...#.#...#...........#.....#.....#.........#.....#...............#.......#.........#
#.###.#.###.#.###.#.###.###.###.#.#.#####.###.#####.#######.#######.#######.#########.#.#####.#.#####.#
#.#...#.#.#...#...#...#.#.......#.#...#.....#.#.....#.......#.....#.#.#...#.#...#.#.#.#.#.#.#.#...#...#
#########.#.#####.#.###.###.#.#####.###.#.#######.###.#.#####.###.#.#.#.#.#.#.###.#.###.#.#.###.#####.#
#...#...#...#.#.#.....#.....#.....#...#.#.....#.....#.#...#.#...#.#.#...#...#.#...............#.#.#.#.#
#.#.###.###.#.#.#.#####.###.#.#.#######.#######.#####.#####.#.#.#.#.#.#######.#.#######.###.#.#.#.#.###
#.#.......................#.#.#...#.....#...#.....#.......#...#.#...#.............#.#.....#.#.#.....#.#
#.###.#####.#####.#####.#####.#########.#.###.###.###.#.#######.###########.###.###.###.#.#####.###.#.#
#.#...#.....#.#...#.....#.#...#...#.......#...#...#.#.#...#.#...#...#.....#.#.#.......#.#.#.......#...#
#.###########.###########.###.#.#######.#.###.###.#.###.###.#.###.#.#.###.#.#.#####.###.#.#.###.#######
#.#.#...#.#.#...#.#.............#.#...#.#...#.#.#.....#.#.#.......#.#.#.......#.#...#...#.#.#...#.....#
###.#.###.#.#.###.#.###.###.#.#.#.#.###.#######.#.#.###.#.#.#.#.###.#.###.#.###.###.#.###.#####.#####.#
#...............#.#.#...#...#.#.....#...#...#...#.#.#.....#.#.#.#.#.#.#.#.#.......#.#.#.#.#.#...#.....#
#.#######.###.###.#########.#.#.#####.###.#####.###.#.###########.#.#.#.#.#.#.###.#####.###.###.###.###
#.#.#.#.#...#...#.#.#.......#.#.....#.......#...#.#.#.#.....#...#.#.#...#.#.#...#.#...#.....#.#.......#
###.#.#.#####.#.#.#.#####.#########.#####.#####.#.#.#.###.#.###.#.#.#.#####.#.#######.###.###.#.#.#####
#.#.....#.#.#.#.....#.#.....#.......#...#...#.....#.#...#.#.#.....#.#...#...#.#.........#.#...#.#.#.#.#
#.#.#####.#.###.#####.#######.#######.#.###.#.#.#.#.###.#.#.#.###.#.#.###########.#.#####.###.#.###.#.#
#.....#.#.#.......#...#.#...#.......#.#...#.#.#.#.#.#.#...#.#...#...#...#...#.#...#.#.#.#.#.#.#...#.#.#
###.###.#.#####.#####.#.#.#.#.#######.###.#.#.#.###.#.#####.###.#.###.###.###.#.###.#.#.#.#.#.#.###.#.#
#.....#...#.#...#...#.#.#.#.......#.....#...#.#.....#...#...#...#.#.#.#.#.#.......#...#...............#
###.#.###.#.###.#.###.#.#######.#.###.#.#####.#######.#.#.#.#.###.#.#.#.#.###.###############.#.###.###
#...#.#.............#.#.#.......#...#.#.....#.....#...#...#.#...#.#.........#...#.....#.#.#.#.#...#.#.#
###.#######.#.###.###.#.#####.#########.#####.#######.#######.#########.#######.###.###.#.#.###.#####.#
#.....#...#.#...#.#.....# E O X A X L #.#...#...#.#.....#...#.#
#.#.###.#####.###.#####.# N C E Y B O #.###.###.#.#.#####.###.#
#.#.....#.#.#.#...#.....# #.#.#.#.#.#.#...#...#...#
#.#.###.#.#.###.#.#.###.# #.#.#.#.#.#.#.#####.###.#
#.#.#.#...#.#...#...#...# #...............#.#.#.#.#
#####.#.#.#.###.#####.### #.#.#.#.#.#.###.#.#.#.#.#
#.#.....#.....#...#...#.# #.#.#.#.#.#.#...#.....#..UW
#.###.###.#.#.###.#.###.# #.###.#####.#.###.#.#.#.#
DK......#.#.#.#.....#......VG EJ....#.#.....#.#...#.#...#
#####.#.###.###.###.##### #############.#.#.#####.#
#.....#...#.#...#...#....SY #...#...#...#...#.#.#...#
#########.#####.#####.### #.###.#####.#####.#.#####
LO......#.....#.#.#...#...# #.........#.....#.#.....#
#.###.#####.#.###.#####.# #.#.###.###.###.###.###.#
#.#.....................# #.#.#.......#.#...#.#.#..XJ
#.#########.###.######### #.#####.#.###.###.#.#.###
#.#.#.....#...#.#.......# VD....#...#.#.......#.....#
#.#.###.#.#########.###.# #.#.###.#####.#####.###.#
#.#.#...#.........#...#..WV #.#.#...#.#...........#.#
###.###.#####.###.###.### #####.###.###############
XE........#...#.#.........# HX....#...#...#...#.....#.#
###########.############# #.###.#####.#.###.###.#.#
#...#.#...#.........#...# #...#.#.#.#...#.....#.#..XB
#.#.#.#.#.#.###.###.###.# #.#####.#.###.###.#.#.#.#
#.#.....#...#.#.#.......# #.#.#.....#.#...#.#.#.#.#
#.#####.#####.#########.# #.#.#####.#.#.#.###.#.#.#
#.#.....#.......#.#.....# #.............#.....#...#
#.#########.###.#.#.##### ###.#.#.###.#.#######.###
HX..#.#.#...#...#.#........OW XY..#.#.#.#...#.#.....#.#.#
###.#.###.#.############# #.#######.#.###.###.###.#
#.#.....#.#.#.#.#.#...#.# #...#.....#.#...#...#...#
#.#.#####.#.#.#.#.#.#.#.# ###.###########.#.###.#.#
#...#.......#.....#.#....QR #.#.#.#.#.......#.#...#..AG
#.#.###.#.#######.#.##### #.#.#.#.#####.###.#.###.#
WB..#.#...#...#.....#...#.# #...............#...#...#
###.#.#.#######.#.###.#.# #.###.###.#.#######.#####
#.#...#.........#.....#.# #.#...#...#.#.#...#.#...#
#.#####################.# #########.###.###.###.#.#
#.......................# #...#...#.#.#...#.....#..DF
#.###.#.#.#####.#######.# ###.#.#.###.###.#.###.#.#
EN..#...#.#...#...#.#...#.# ZH......#.............#.#.#
#######.#.#.#.###.#.#.#.# ###.###.#######.#.###.###
#...#.#.#.#.#.#.....#...# DF..#.#.....#.....#.#...#.#
###.#.###.###.###.#.##### #.#####.###############.#
#.......#...#.#...#......KN #.#...#.#...#.....#.#...#
###.#.#########.######### #.###.###.#######.#.#.#.#
#...#.#.#.#...#.#.......# #.....................#..GL
#.#.###.#.###.#####.#.### #########################
#.#...#.......#...#.#....AG WW..#.................#...#
#.#.#.#.#########.#.#.### #.#.###.###.#.#####.#.#.#
ZH..#.#.#.#.#...#.....#.#.# #.....#...#.#...#.....#..RP
#####.#.#.#.###.#.#.#.#.# ###.###.#####.#.###.###.#
#...............#.#.#...# #...#.#...#...#.#.....#.#
###.###.###.#.#.#.###.### X S U R W D G ###.#.#.#.###.###.###.###
#...#.#...#.#.#.#.#...#.# J H W P B K L #.#...#.#.#.#.#.#.#.....#
#####.#.###.#.###.#####.#######.#######.#####.###.#####.###########.#.#########.#.#.###.#.#.#.#####.#.#
#.#.....#.#.#...#...#.#.....#.#.....#...#.........#.........#.......#.........#...#...#.#.#.......#.#.#
#.###.#.#.#.#########.#.#####.#.#######.#####.###.#.#.#.#####.#####.#.###.#######.#####.#.###.###.#.#.#
#.#...#.#.......#...............#.#...#.....#.#.#.#.#.#.#...#.#...#.#.#...#...#.#.....#...#.....#.#.#.#
#.###.###.#########.#.#.#####.###.#.###.#.###.#.#####.#####.#.#.#.#######.###.#.###.#####.###.#########
#.......#.#.#.....#.#.#.#.............#.#.#.........#...#.....#.#.....#.........#...#.#...#...........#
#.###.###.#.#.#########.#####.#####.#####.###.#######.###.#.#.#.###.###.###.###.#####.#####.#.#.#####.#
#.#.....#.....#.....#...#.#.#.....#.#.......#.#.#...#...#.#.#...#...#.....#.#...........#.#.#.#.....#.#
#######.###.###.#######.#.#.#.#.#######.###.#.#.#.###.###########.#######.###########.#.#.#####.#####.#
#.......#...........#.#.#.....#.#.#...#.#...#.....#.......#.#...#.#...#.........#...#.#.....#.......#.#
#.#.#####.#.#.#.#.#.#.###.###.###.#.###.#.#.#.#######.#####.###.#.#.#.#.#########.###########.###.#####
#.#.#.#...#.#.#.#.#.#.#.#.#.#.........#.#.#.#.#.#.#.....#...#.......#.#...#.................#.#.......#
###.#.###.###.###.#.#.#.###.#.#.###########.#.#.#.###.###.###.###.#######.#.#####.#.#.###.#######.#.###
#.......#...#...#.#.......#...#.#.......#...#.....#.#.....#.#.#.....#...........#.#.#...#.....#...#.#.#
###.#####.#####.#.#.#.#####.#.#####.###.###.###.###.#.#####.#######.#.###.###.###.#######.###.###.###.#
#.....#...#.....#.#.#.#...#.#.....#.#...#.#.#.....#.....#.....#.....#.#...#...#.......#...#.....#.....#
###.#####.###.###########.#####.#######.#.#.#.#.#####.#######.#.#####.#####.#######.###.#.#####.###.###
#...#.#.....#.#.#.......#.......#...#.#.....#.#.#...#.....#.#.......#...#.#.#.#.#.#...#.#.#.#.#...#...#
#####.#########.###.###.#####.#####.#.###.###.#####.#.#####.#######.#.###.###.#.#.#.#######.#.#########
#.#.......#.#.#.....#.#.............#.....#.#.....#.#...#.....#.....#.#...#.#.#.#.#...#...#...........#
#.###.#####.#.#.#####.#####.#.#.###.#.#####.#.#.#.#.#.###.#.#####.###.#.#.#.#.#.#.#####.#####.#####.###
#...............#.#.#.......#.#...#.#.......#.#.#...#.#...#.#.#.#...#...#.................#.......#...#
#.#.#.#.#.#####.#.#.#.#.#.#.#.#####.#.#.###.#.#####.#.#.###.#.#.###.#.###.#.#.###.#.#.#.#####.#########
#.#.#.#.#.#.....#.....#.#.#.#.#.....#.#.#...#.#.....#...#...#.......#.#...#.#.#...#.#.#...............#
###############################.###.#####.#####.#.#######.###.#########.###############################
X Z V O O S W E
Y Z G C W Y W J

19
input/day20_example1.txt Normal file
View File

@@ -0,0 +1,19 @@
A
A
#######.#########
#######.........#
#######.#######.#
#######.#######.#
#######.#######.#
##### B ###.#
BC...## C ###.#
##.## ###.#
##...DE F ###.#
##### G ###.#
#########.#####.#
DE..#######...###.#
#.#########.###.#
FG..#########.....#
###########.#####
Z
Z

37
input/day20_example2.txt Normal file
View File

@@ -0,0 +1,37 @@
Z L X W C
Z P Q B K
###########.#.#.#.#######.###############
#...#.......#.#.......#.#.......#.#.#...#
###.#.#.#.#.#.#.#.###.#.#.#######.#.#.###
#.#...#.#.#...#.#.#...#...#...#.#.......#
#.###.#######.###.###.#.###.###.#.#######
#...#.......#.#...#...#.............#...#
#.#########.#######.#.#######.#######.###
#...#.# F R I Z #.#.#.#
#.###.# D E C H #.#.#.#
#.#...# #...#.#
#.###.# #.###.#
#.#....OA WB..#.#..ZH
#.###.# #.#.#.#
CJ......# #.....#
####### #######
#.#....CK #......IC
#.###.# #.###.#
#.....# #...#.#
###.### #.#.#.#
XF....#.# RF..#.#.#
#####.# #######
#......CJ NM..#...#
###.#.# #.###.#
RE....#.# #......RF
###.### X X L #.#.#.#
#.....# F Q P #.#.#.#
###.###########.###.#######.#########.###
#.....#...#.....#.......#...#.....#.#...#
#####.#.###.#######.#######.###.###.#.#.#
#.......#.......#.#.#.#.#...#...#...#.#.#
#####.###.#####.#.#.#.#.###.###.#.###.###
#.......#.....#.#...#...............#...#
#############.#.#.###.###################
A O F N
A A D M

View File

@@ -1,5 +1,7 @@
extern crate core;
mod tasks; mod tasks;
fn main() { fn main() {
tasks::day19::run(); tasks::day20::run();
} }

View File

@@ -1,7 +1,8 @@
use std::collections::HashMap;
use super::day05::{IntCodeComputer, RAM}; use super::day05::{IntCodeComputer, RAM};
use itertools::Itertools; use itertools::Itertools;
use std::collections::HashMap;
#[allow(dead_code)]
pub fn run() { pub fn run() {
let program = super::day05::load_ram("input/day19.txt"); let program = super::day05::load_ram("input/day19.txt");
part1(&program, 50); part1(&program, 50);
@@ -12,9 +13,7 @@ fn part1(program: &RAM, max_perimeter: i128) {
let result = (0..max_perimeter) let result = (0..max_perimeter)
.flat_map(|x| { .flat_map(|x| {
(0..max_perimeter) (0..max_perimeter)
.map(|y| { .map(|y| read_coordinate(program, x, y))
read_coordinate(program, x, y)
})
.collect_vec() .collect_vec()
}) })
.filter(|v| *v) .filter(|v| *v)
@@ -27,13 +26,11 @@ const SHIP_SIZE: i128 = 100;
fn part2(program: &RAM) { fn part2(program: &RAM) {
let mut map: HashMap<(i128, i128), bool> = HashMap::new(); let mut map: HashMap<(i128, i128), bool> = HashMap::new();
(0..SHIP_SIZE) (0..SHIP_SIZE).for_each(|x| {
.for_each(|x| { (0..SHIP_SIZE).for_each(|y| {
(0..SHIP_SIZE) map.insert((x, y), read_coordinate(program, x, y));
.for_each(|y| { })
map.insert((x, y), read_coordinate(program, x, y)); });
})
});
for perimeter in 0.. { for perimeter in 0.. {
extend_horizon(program, &mut map, perimeter); extend_horizon(program, &mut map, perimeter);
if let Some((x, y)) = check_all_squares_starting_at(&map, perimeter) { if let Some((x, y)) = check_all_squares_starting_at(&map, perimeter) {
@@ -44,7 +41,10 @@ fn part2(program: &RAM) {
} }
} }
fn check_all_squares_starting_at(map: &HashMap<(i128, i128), bool>, perimeter: i128) -> Option<(i128, i128)> { fn check_all_squares_starting_at(
map: &HashMap<(i128, i128), bool>,
perimeter: i128,
) -> Option<(i128, i128)> {
for i in 0..=perimeter { for i in 0..=perimeter {
if let Some(point) = check_fits(map, i, perimeter) { if let Some(point) = check_fits(map, i, perimeter) {
return Some(point); return Some(point);

363
src/tasks/day20.rs Normal file
View File

@@ -0,0 +1,363 @@
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::curried_factory);
let part1 = maze.shortest_path();
println!("Part 1: {}", part1);
let maze = Maze::from(&input, DimensionField::curried_factory);
let part1 = maze.shortest_path();
println!("Part 2: {}", part1);
}
type C = i32;
type FieldFactory = Box<dyn Fn(&MapPoint) -> Box<dyn Field>>;
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
struct MapPoint {
x: C,
y: C,
}
impl MapPoint {
fn of(x: C, y: C) -> Self {
MapPoint { x, y }
}
fn neighbors(self) -> Vec<MapPoint> {
vec![
MapPoint::of(self.x + 1, self.y),
MapPoint::of(self.x, self.y + 1),
MapPoint::of(self.x - 1, self.y),
MapPoint::of(self.x, self.y - 1),
]
}
}
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
struct RealPoint {
x: C,
y: C,
level: usize,
}
impl RealPoint {
fn map_point(&self) -> MapPoint {
MapPoint {
x: self.x,
y: self.y,
}
}
}
impl RealPoint {
fn from(map_point: MapPoint, level: usize) -> Self {
RealPoint {
x: map_point.x,
y: map_point.y,
level,
}
}
}
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 curried_factory(width: C, height: C) -> FieldFactory
where
Self: Sized;
}
struct PortalField {
neighbors: Vec<MapPoint>,
}
impl PortalField {
fn new() -> Self {
PortalField { neighbors: vec![] }
}
}
impl Field for PortalField {
fn neighbors(&self, _: usize) -> Vec<RealPoint> {
self.neighbors
.iter()
.map(|p| RealPoint::from(*p, 0))
.collect()
}
fn set_label_partner(&mut self, point: MapPoint) {
self.neighbors.push(point);
}
fn set_neighbors(&mut self, neighbors: Vec<MapPoint>) {
self.neighbors = neighbors;
}
fn curried_factory(_: C, _: C) -> FieldFactory {
Box::new(|_| Box::new(PortalField::new()))
}
}
struct DimensionField {
point: MapPoint,
neighbors: Vec<MapPoint>,
jump: Option<MapPoint>,
map_width: C,
map_height: C,
}
impl DimensionField {
fn is_inward(&self) -> bool {
let p = self.point;
p.x > 2 && p.x < self.map_width - 3 && p.y > 2 && p.y < self.map_height - 3
}
}
impl Field for DimensionField {
fn neighbors(&self, at_level: usize) -> Vec<RealPoint> {
let mut result: Vec<RealPoint> = self
.neighbors
.iter()
.map(|n| RealPoint::from(*n, at_level))
.collect();
if let Some(destination) = self.jump {
if self.is_inward() {
result.push(RealPoint::from(destination, at_level + 1));
} else if at_level > 0 {
result.push(RealPoint::from(destination, at_level - 1));
}
}
result
}
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>>;
struct Maze {
map: FieldMap,
start: RealPoint,
finish: RealPoint,
}
impl Maze {
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, factory(width, height));
Self::add_physical_neighbors(&mut map);
let labels = Self::labels(&moc, width, height);
Self::process_labels(&mut map, &labels);
let start = labels["AA"][0];
let finish = labels["ZZ"][0];
Maze {
map,
start: RealPoint::from(start, 0),
finish: RealPoint::from(finish, 0),
}
}
fn shortest_path(&self) -> usize {
bfs(&self.map, self.start, self.finish)
}
fn process_labels(map: &mut FieldMap, labels: &HashMap<String, Vec<MapPoint>>) {
for (label, points) in labels {
if label == "AA" || label == "ZZ" {
continue;
}
map.get_mut(&points[0])
.unwrap()
.set_label_partner(points[1]);
map.get_mut(&points[1])
.unwrap()
.set_label_partner(points[0]);
}
}
fn labels(
moc: &HashMap<MapPoint, char>,
width: C,
height: C,
) -> HashMap<String, Vec<MapPoint>> {
let horizontal: Vec<(String, MapPoint)> = (0..width - 2)
.into_iter()
.flat_map(|x| {
(0..height).into_iter().flat_map(move |y| {
let mut triple = [
moc[&MapPoint::of(x, y)],
moc[&MapPoint::of(x + 1, y)],
moc[&MapPoint::of(x + 2, y)],
];
let left = Self::label(triple).map(|label| (label, MapPoint::of(x, y)));
triple.reverse();
let right = Self::label(triple).map(|label| (label, MapPoint::of(x + 2, y)));
vec![left, right]
})
})
.flatten()
.collect();
let vertical: Vec<(String, MapPoint)> = (0..width)
.into_iter()
.flat_map(|x| {
(0..height - 2).into_iter().flat_map(move |y| {
let mut triple = [
moc[&MapPoint::of(x, y)],
moc[&MapPoint::of(x, y + 1)],
moc[&MapPoint::of(x, y + 2)],
];
let left = Self::label(triple).map(|label| (label, MapPoint::of(x, y)));
triple.reverse();
let right = Self::label(triple).map(|label| (label, MapPoint::of(x, y + 2)));
vec![left, right]
})
})
.flatten()
.collect();
let mut result = HashMap::new();
for (s, p) in horizontal.into_iter().chain(vertical.into_iter()) {
if !result.contains_key(&s) {
result.insert(s.clone(), vec![]);
}
result.get_mut(&s).unwrap().push(p);
}
result
}
fn label(chars: [char; 3]) -> Option<String> {
if chars[0] == '.' && chars[1].is_alphabetic() && chars[2].is_alphabetic() {
let label = if chars[1] < chars[2] {
format!("{}{}", chars[1], chars[2])
} else {
format!("{}{}", chars[2], chars[1])
};
Some(label)
} else {
None
}
}
fn add_physical_neighbors(map: &mut FieldMap) {
let points: HashSet<MapPoint> = map.keys().map(|p| *p).collect();
map.iter_mut().for_each(|(p, f)| {
let neighbors = p
.neighbors()
.into_iter()
.filter(|neighbor| points.contains(neighbor))
.collect();
f.set_neighbors(neighbors);
})
}
fn create_map_of_free_spots(
moc: &HashMap<MapPoint, char>,
field_factory: FieldFactory,
) -> FieldMap {
moc.keys()
.filter(|p| moc[p] == '.')
.map(|p| (*p, field_factory(p)))
.collect()
}
fn map_of_chars(input: &String) -> (HashMap<MapPoint, char>, C, C) {
let mut map: HashMap<MapPoint, char> = input
.lines()
.enumerate()
.flat_map(|(y, line)| {
line.chars()
.enumerate()
.map(move |(x, c)| (MapPoint::of(x as C, y as C), c))
})
.collect();
let width = map.keys().map(|p| p.x).max().unwrap() + 1;
let height = map.keys().map(|p| p.y).max().unwrap() + 1;
for x in 0..width {
for y in 0..height {
if !map.contains_key(&MapPoint::of(x, y)) {
map.insert(MapPoint::of(x, y), ' ');
}
}
}
(map, width, height)
}
}
fn bfs(map: &FieldMap, start: RealPoint, finish: RealPoint) -> usize {
let mut open: VecDeque<(RealPoint, usize)> = VecDeque::new();
let mut seen: HashSet<RealPoint> = HashSet::new();
open.push_back((start, 0));
seen.insert(start);
while let Some((p, d)) = open.pop_front() {
if p == finish {
return d;
}
for neighbor in map[&p.map_point()].neighbors(p.level) {
if !seen.contains(&neighbor) {
open.push_back((neighbor, d + 1));
seen.insert(neighbor);
}
}
}
panic!("no path found")
}
#[cfg(test)]
mod test {
use crate::tasks::day20::{DimensionField, Field, Maze, PortalField};
#[test]
fn example_part1() {
let input = std::fs::read_to_string("input/day20_example1.txt").unwrap();
let maze = Maze::from(&input, PortalField::curried_factory);
assert_eq!(maze.shortest_path(), 23);
}
#[test]
fn example_part2() {
let input = std::fs::read_to_string("input/day20_example2.txt").unwrap();
let maze = Maze::from(&input, DimensionField::curried_factory);
assert_eq!(maze.shortest_path(), 396);
}
#[test]
fn result() {
let input = std::fs::read_to_string("input/day20.txt").unwrap();
let maze = Maze::from(&input, PortalField::curried_factory);
assert_eq!(maze.shortest_path(), 454);
let maze = Maze::from(&input, DimensionField::curried_factory);
assert_eq!(maze.shortest_path(), 5744);
}
}

View File

@@ -16,6 +16,7 @@ pub mod day16;
pub mod day17; pub mod day17;
pub mod day18; pub mod day18;
pub mod day19; pub mod day19;
pub mod day20;
pub mod day21; pub mod day21;
#[allow(dead_code)] #[allow(dead_code)]
pub mod day22; pub mod day22;