diff --git a/day08/Cargo.toml b/day08/Cargo.toml new file mode 100644 index 0000000..0a2627e --- /dev/null +++ b/day08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day08" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day08/src/main.rs b/day08/src/main.rs new file mode 100644 index 0000000..4f0f8a9 --- /dev/null +++ b/day08/src/main.rs @@ -0,0 +1,99 @@ +use std::iter; +use std::collections::HashSet; +use std::collections::HashMap; +use std::fs; +use std::env; + +type Coord = (i32, i32); + +fn main() { + println!("Hello, AoC day 04!"); + + let args: Vec = env::args().collect(); + if args.len() != 2 { + println!("wrong number of arguments!"); + std::process::exit(1); + } + + let file_path = &args[1]; + + let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); + let mut grid: HashMap = HashMap::new(); + + let mut x; + // build our grid! + let mut y = 0; + for line in contents.lines() { + x = 0; + for c in line.chars() { + grid.insert((x,y), c); + x += 1; + } + y += 1; + } + + let mut antennas: HashMap> = HashMap::new(); + let mut antinodes: HashSet = HashSet::new(); + + for (&location, &character) in grid.iter() { + if character == '.' { continue; } + + if antennas.contains_key(&character) { + let other_antennas = antennas.get(&character).unwrap(); + for &other_location in other_antennas { + let a = antinode(location, other_location); + if grid.contains_key(&a) { antinodes.insert(a); } + let b = antinode(other_location, location); + if grid.contains_key(&b) { antinodes.insert(b); } + } + } else { + antennas.insert(character, Vec::new()); + } + + antennas.get_mut(&character).unwrap().push(location); + } + + let count = antinodes.len(); + println!("there are {count} antinodes in the naive assumption"); + + let mut antennas_b: HashMap> = HashMap::new(); + let mut antinodes_b: HashSet = HashSet::new(); + + for (&location, &character) in grid.iter() { + if character == '.' { continue; } + + if antennas_b.contains_key(&character) { + let other_antennas = antennas_b.get(&character).unwrap(); + for &other_location in other_antennas { + for node in find_antinodes(location, other_location) { + if grid.contains_key(&node) { antinodes_b.insert(node); } + else { break; } + } + } + for &other_location in other_antennas { + for node in find_antinodes(other_location, location) { + if grid.contains_key(&node) { antinodes_b.insert(node); } + else { break; } + } + } + } else { + antennas_b.insert(character, Vec::new()); + } + + antennas_b.get_mut(&character).unwrap().push(location); + } + + let count_b = antinodes_b.len(); + println!("there are {count_b} antinodes in the complex scenario"); +} + +fn antinode(a: Coord, b: Coord) -> Coord { + let a_to_b = ( b.0 - a.0, b.1 - a.1 ); + return ( b.0 + a_to_b.0, b.1 + a_to_b.1 ); +} + +fn find_antinodes(a: Coord, b: Coord) -> impl Iterator { + let a_to_b = ( b.0 - a.0, b.1 - a.1 ); + return iter::successors(Some( b ), + move |&x| Some((x.0 + a_to_b.0, x.1 + a_to_b.1))) +} \ No newline at end of file