From cfd9b4f2ad1a09bedf7f764f84448a61faab54a3 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 20:26:02 +0200 Subject: Refile for merging repos --- 2018/src/bin/day_20.rs | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 2018/src/bin/day_20.rs (limited to '2018/src/bin/day_20.rs') diff --git a/2018/src/bin/day_20.rs b/2018/src/bin/day_20.rs new file mode 100644 index 0000000..6486d72 --- /dev/null +++ b/2018/src/bin/day_20.rs @@ -0,0 +1,137 @@ +extern crate advent_of_code_2018; +use advent_of_code_2018::*; + +use std::error::Error; +use std::path::PathBuf; + +use std::collections::{HashSet, HashMap}; + +// cargo watch -cs "cargo run --release --bin day_20" + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +enum Dir { + N, S, E, W +} + +#[derive(Debug)] +struct Room { + doors: HashSet +} + +impl Room { + fn new() -> Room { + Room { + doors: HashSet::new() + } + } +} + +fn main() -> Result<(), Box> { + let input = &read_file(&PathBuf::from("inputs/20.txt"))?[0]; + + println!("Input: {:?}", input); + + let rooms = populate_rooms(input); + let distances = distance_map(&rooms); + + debug!(distance_to_furthest_room(&distances)); + debug!(distances_more_than_1000(&distances)); + + Ok(()) +} + +fn populate_rooms(input: &str) -> HashMap<(i32, i32), Room> { + let mut rooms: HashMap<(i32, i32), Room> = HashMap::new(); + rooms.insert((0,0), Room::new()); + + let mut coords = vec!((0, 0)); + + let mut coord_stack: Vec<(Vec<(i32, i32)>, Vec<(i32, i32)>)> = Vec::new(); + + for c in input.chars() { + match c { + '^' | '$' => {}, + 'E' => { + for coord in &mut coords { + rooms.get_mut(coord).unwrap().doors.insert(Dir::E); + coord.0 += 1; + rooms.entry(*coord).or_insert(Room::new()); + } + }, + 'W' => { + for coord in &mut coords { + rooms.get_mut(coord).unwrap().doors.insert(Dir::W); + coord.0 -= 1; + rooms.entry(*coord).or_insert(Room::new()); + } + }, + 'N' => { + for coord in &mut coords { + rooms.get_mut(coord).unwrap().doors.insert(Dir::N); + coord.1 -= 1; + rooms.entry(*coord).or_insert(Room::new()); + } + }, + 'S' => { + for coord in &mut coords { + rooms.get_mut(coord).unwrap().doors.insert(Dir::S); + coord.1 += 1; + rooms.entry(*coord).or_insert(Room::new()); + } + }, + '(' => { + coord_stack.push((coords.clone(), Vec::new())); + }, + '|' => { + coord_stack.last_mut().unwrap().1.append(&mut coords); + coords = coord_stack.last().unwrap().0.clone(); + }, + ')' => { + coord_stack.last_mut().unwrap().1.append(&mut coords); + coords = coord_stack.pop().unwrap().1; + coords.sort(); + coords.dedup(); + }, + c => { + panic!("Unknown character {}", c); + } + } + } + + debug!(rooms.len()); + + rooms +} + +fn distance_map(rooms: &HashMap<(i32, i32), Room>) -> HashMap<(i32, i32), u32> { + let mut distances: HashMap<(i32, i32), u32> = HashMap::new(); + distances.insert((0,0), 0); + + while distances.len() < rooms.len() { + let current_max = *distances.values().max().unwrap(); + let new_distances = distances.iter() + .filter(|(_, &d)| d == current_max) + .flat_map(|(&coord, _)| { + let room = rooms.get(&coord).unwrap(); + room.doors.iter().map(|dir| match dir { + Dir::N => (coord.0, coord.1-1), + Dir::S => (coord.0, coord.1+1), + Dir::W => (coord.0-1, coord.1), + Dir::E => (coord.0+1, coord.1) + }).collect::>() + }) + .collect::>(); + for coord in new_distances { + distances.entry(coord).or_insert(current_max + 1); + } + } + distances +} + +fn distance_to_furthest_room(distances: &HashMap<(i32, i32), u32>) -> u32 { + distances.values().max().unwrap().clone() +} + +fn distances_more_than_1000(distances: &HashMap<(i32, i32), u32>) -> u32 { + distances.values().filter(|&&x| x >= 1000).count() as u32 +} -- cgit v1.2.3