day20 part 2

This commit is contained in:
Johannes Schaefer
2018-12-21 11:26:21 +01:00
parent 241ca8ea18
commit 8badd4a416

View File

@@ -1,9 +1,8 @@
use self::Tile::*; use self::Tile::*;
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::utils; use crate::utils;
use std::collections::{HashMap, HashSet};
use std::ops::Add;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::collections::{HashMap, HashSet};
pub fn task1() { pub fn task1() {
let input = utils::read_file("input/day20.txt"); let input = utils::read_file("input/day20.txt");
@@ -15,7 +14,14 @@ pub fn task1() {
// print_map(&map); // print_map(&map);
println!("Most distant point: {:?}", longest_shortest_path(&map, Point(0,0))); println!(
"Most distant point: {:?}",
longest_shortest_path(&map, Point(0, 0))
);
println!(
"Rooms with minimal distance >= 1000: {}",
count_long_distances(&map, Point(0, 0), 1000)
);
} }
/// Returns the end points of the parsed input /// Returns the end points of the parsed input
@@ -23,7 +29,7 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) ->
// println!("{}, {:?}", input, position); // println!("{}, {:?}", input, position);
if input == "$" { if input == "$" {
println!("End of the road."); println!("End of the road.");
return vec!(position).into_iter().collect(); return vec![position].into_iter().collect();
} }
let mut position = position; let mut position = position;
let mut input = input; let mut input = input;
@@ -81,7 +87,7 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) ->
), ),
} }
} }
vec!(position).into_iter().collect() vec![position].into_iter().collect()
} }
/// Splits the input by '|', but only by those that are not enclosed by further parenthesises. /// Splits the input by '|', but only by those that are not enclosed by further parenthesises.
@@ -167,9 +173,9 @@ fn print_map(map: &HashMap<Point, Tile>) {
fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Point, usize)> { fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Point, usize)> {
let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len()); let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len());
let mut open: VecDeque<(usize,Point)> = VecDeque::new(); let mut open: VecDeque<(usize, Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new(); let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0,start)); open.push_back((0, start));
visited.insert(start); visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() { while let Some((distance, predecessor)) = open.pop_front() {
distances.insert(predecessor, distance); distances.insert(predecessor, distance);
@@ -178,7 +184,7 @@ fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Po
let room = predecessor.next_room(&p); let room = predecessor.next_room(&p);
if !visited.contains(&room) { if !visited.contains(&room) {
visited.insert(room); visited.insert(room);
open.push_back((distance + 1, room)); open.push_back((distance + 1, room));
} }
} }
} }
@@ -190,6 +196,30 @@ fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Po
} }
} }
fn count_long_distances(map: &HashMap<Point, Tile>, start: Point, threshold: usize) -> usize {
let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len());
let mut open: VecDeque<(usize, Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0, start));
visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() {
distances.insert(predecessor, distance);
for p in predecessor.neighbors() {
if let Some(Door) = map.get(&p) {
let room = predecessor.next_room(&p);
if !visited.contains(&room) {
visited.insert(room);
open.push_back((distance + 1, room));
}
}
}
}
distances
.iter()
.filter(|(_, distance)| **distance >= threshold)
.count()
}
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)] #[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
struct Point(i32, i32); struct Point(i32, i32);
@@ -213,7 +243,10 @@ impl Point {
} }
fn next_room(&self, other: &Self) -> Self { fn next_room(&self, other: &Self) -> Self {
Point(self.0 + 2*(other.0 - self.0), self.1 +2*(other.1-self.1)) Point(
self.0 + 2 * (other.0 - self.0),
self.1 + 2 * (other.1 - self.1),
)
} }
} }