diff --git a/crates/day_8/src/map.rs b/crates/day_8/src/map.rs index cc67f24..e76a642 100644 --- a/crates/day_8/src/map.rs +++ b/crates/day_8/src/map.rs @@ -11,7 +11,7 @@ // single lowercase letter, uppercase letter, or digit. -use std::{collections::HashMap, mem}; +use std::{io::prelude::*, fs::File, collections::HashMap, mem}; use nalgebra_glm::Vec2; @@ -38,10 +38,31 @@ impl PointIdx PointIdx { i, j } } - // pub fn as_glm_vec(self: & PointIdx) -> I32Vec2 - // { - // I32Vec2::new(self.i as i32, self.j as i32) - // } + pub fn from_glm_vec(glm_vec: &Vec2) -> PointIdx + { + PointIdx{ i: glm_vec.x as usize, j: glm_vec.y as usize } + } + + pub fn as_glm_vec(self: & PointIdx) -> Vec2 + { + Vec2::new(self.i as f32, self.j as f32) + } + +} + +#[derive(Copy, Clone, PartialEq, Debug)] +pub struct Antinode +{ + location: PointIdx, + freq: u8, +} + +impl Antinode +{ + pub fn new(location: PointIdx, freq: u8) -> Antinode + { + Antinode { location, freq } + } } #[derive(Clone, Debug)] @@ -49,18 +70,22 @@ pub struct Map { map: Vec>, antenna_locations: HashMap>, - antinodes: Vec, + antinodes: Vec, + + // DEBUG STUFF + first_processed_freq: u8, } impl Map { pub fn new() -> Map { - Map { map: vec![], antenna_locations: HashMap::new(), antinodes: vec![] } + Map { map: vec![], antenna_locations: HashMap::new(), antinodes: vec![], first_processed_freq: 0 } } pub fn parse(data: &str) -> Map { + // let mut num_freqs = 0; let mut split_pattern = "\n"; if data.contains("\r\n") { @@ -101,10 +126,14 @@ impl Map } } + map.push(parsed_row); } - Map { map, antenna_locations, antinodes: vec![] } + // DEBUG: + // println!("num freqs found: {}", antenna_locations.len()); + + Map { map, antenna_locations, antinodes: vec![], first_processed_freq: 0 } } pub fn double_check_antenna_locations(self: &Map) -> bool @@ -141,22 +170,18 @@ impl Map { print!("MAP:"); } - for (i, row) in self.map.iter().enumerate() + for (_i, row) in self.map.iter().enumerate() { print!("\n\t"); - for (j, c) in row.iter().enumerate() + for (_j, c) in row.iter().enumerate() { - if include_antinodes && self.antinodes.contains(&PointIdx::new(i, j)) + match c { - print!("#"); - } - else - { - match c + MapCell::Empty => print!("."), + MapCell::Freq(f) => { - MapCell::Empty => print!("."), - MapCell::Freq(f) => print!("{}", *f as char), - } + print!("{}", *f as char); + }, } } } @@ -168,6 +193,40 @@ impl Map println!("{:#?}", self.antenna_locations); } + pub fn dump_map_data_by_freq(self: &Map, filename: &str) + { + let mut file = File::create("foo.txt").expect(&format!("Failed to create file {}", filename)); + for (freq, _locations) in &self.antenna_locations + { + file.write_all(&format!("\nMap for freq: {}", *freq as char).as_bytes()).expect("Failed to write to file!"); + + for (_i, row) in self.map.iter().enumerate() + { + file.write_all(b"\n\t").expect("Failed to write to file again"); + for (_j, c) in row.iter().enumerate() + { + + match c + { + MapCell::Empty => file.write_all(b".").expect("Failed to write to file (in match statement)"), + MapCell::Freq(f) => + { + if *freq == *f + { + file.write_all(&format!("{}", *f as char).as_bytes()).expect("Failed to write to file (in match statement 2)"); + } + else + { + file.write_all(b".").expect("Failed to write to file (in match statement 3)"); + } + }, + } + } + } + } + + } + // an antinode occurs at any point that is perfectly in line with two antennas of the same // frequency - but only when one of the antennas is twice as far away as the other // This means that for any pair of antennas with the same frequency, there are two antinodes, one on either side of them. @@ -185,11 +244,12 @@ impl Map // .......... // .......... - pub fn find_antinodes(self: &mut Map) -> Vec + pub fn find_antinodes(self: &mut Map) -> Vec { - let mut antinodes: Vec = vec![]; - for (_freq, locations) in &self.antenna_locations + let mut antinodes: Vec = vec![]; + for (freq, locations) in &self.antenna_locations { + self.first_processed_freq = *freq; let mut i = 0; while i < locations.len() { @@ -214,26 +274,22 @@ impl Map let direction = (second_glm - first_glm).normalize(); - let new_i = (locations[i].i as f32 + direction.x * dist); - let new_j = (locations[i].j as f32 + direction.y * dist); + let new_i = locations[i].i as f32 + direction.x * dist; + let new_j = locations[i].j as f32 + direction.y * dist; - if new_i < 0.0 || new_j < 0.0 - { - j += 1; - continue; - } - if new_i >= self.map.len() as f32 || + if new_i < 0.0 || new_j < 0.0 || + new_i >= self.map.len() as f32 || new_j >= self.map[0].len() as f32 { j += 1; continue; } - let antinode_location = PointIdx::new(new_i as usize, new_j as usize); + let antinode = Antinode::new(PointIdx::new(new_i as usize, new_j as usize), *freq); - if !antinodes.contains(&antinode_location) + if !antinodes.contains(&antinode) { - antinodes.push(antinode_location); + antinodes.push(antinode); } j += 1;