day20 part 2
This commit is contained in:
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user