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::*;
#[allow(unused_imports)]
use crate::utils;
use std::collections::{HashMap, HashSet};
use std::ops::Add;
use std::collections::VecDeque;
use std::collections::{HashMap, HashSet};
pub fn task1() {
let input = utils::read_file("input/day20.txt");
@@ -15,7 +14,14 @@ pub fn task1() {
// 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
@@ -23,7 +29,7 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) ->
// println!("{}, {:?}", input, position);
if input == "$" {
println!("End of the road.");
return vec!(position).into_iter().collect();
return vec![position].into_iter().collect();
}
let mut position = position;
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.
@@ -167,9 +173,9 @@ fn print_map(map: &HashMap<Point, Tile>) {
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 open: VecDeque<(usize,Point)> = VecDeque::new();
let mut open: VecDeque<(usize, Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0,start));
open.push_back((0, start));
visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() {
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);
if !visited.contains(&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)]
struct Point(i32, i32);
@@ -213,7 +243,10 @@ impl Point {
}
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),
)
}
}