|
|
|
|
@ -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<Vec<MapCell>>,
|
|
|
|
|
antenna_locations: HashMap<u8, Vec<PointIdx>>,
|
|
|
|
|
antinodes: Vec<PointIdx>,
|
|
|
|
|
antinodes: Vec<Antinode>,
|
|
|
|
|
|
|
|
|
|
// 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<PointIdx>
|
|
|
|
|
pub fn find_antinodes(self: &mut Map) -> Vec<Antinode>
|
|
|
|
|
{
|
|
|
|
|
let mut antinodes: Vec<PointIdx> = vec![];
|
|
|
|
|
for (_freq, locations) in &self.antenna_locations
|
|
|
|
|
let mut antinodes: Vec<Antinode> = 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;
|
|
|
|
|
|