--- /dev/null
+use std::error::Error;
+use std::path::Path;
+use std::collections::{HashMap, HashSet};
+
+struct Puzzle {
+ map: HashMap<(isize, isize), char>,
+}
+
+impl Puzzle {
+ pub fn new(input: &str) -> Self {
+ let mut map = HashMap::new();
+ input.lines()
+ .enumerate()
+ .for_each(|(row, l)| {
+ l.chars()
+ .enumerate()
+ .for_each(|(col, c)| {
+ map.insert((row as isize, col as isize), c);
+ });
+ });
+ Self { map }
+ }
+}
+
+fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 1", get_day());
+
+ let puzzle = Puzzle::new(input);
+ let mut visited: HashSet<(isize, isize)> = HashSet::new();
+ let mut antinodes: HashSet<(isize, isize)> = HashSet::new();
+
+ puzzle.map.iter()
+ .filter(|(_, value)| **value != '.')
+ .for_each(|(key, value)| {
+ if !visited.contains(key) {
+ visited.insert(*key);
+
+ puzzle.map.iter()
+ .filter(|(k, v)| *v == value && *k != key)
+ .for_each(|(k, v)| {
+ let x1 = if k <= key { k } else { key };
+ let x2 = if k <= key { key } else { k };
+ let d = (x1.0 - x2.0, x1.1 - x2.1);
+ for a in [(x1.0 + d.0, x1.1 + d.1), (x2.0 - d.0, x2.1 - d.1)] {
+ if puzzle.map.contains_key(&a) {
+ antinodes.insert(a);
+ }
+ }
+ });
+ }
+ });
+
+ let res = antinodes.len() as u32;
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 2", get_day());
+
+ Ok(0)
+}
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+ let res = run_part1(&input)?;
+ println!("{res}");
+
+ let res = run_part2(&input)?;
+ println!("{res}");
+
+ Ok(())
+}
+
+fn get_day() -> String {
+ let filename = file!();
+ Path::new(filename).file_stem().unwrap().to_str().unwrap().to_string()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static TEXT_INPUT: &str = "\
+............
+........0...
+.....0......
+.......0....
+....0.......
+......A.....
+............
+............
+........A...
+.........A..
+............
+............";
+
+ #[test]
+ fn test_part1() {
+ assert_eq!(14, run_part1(TEXT_INPUT).unwrap());
+ }
+
+ #[test]
+ fn test_part2() {
+ assert_eq!(0, run_part2(TEXT_INPUT).unwrap());
+ }
+}
pub mod day05;
pub mod day06;
pub mod day07;
+pub mod day08;
fn main() {
let args: Vec<String> = env::args().collect();
"day05" => day05::run(&input)?,
"day06" => day06::run(&input)?,
"day07" => day07::run(&input)?,
+ "day08" => day08::run(&input)?,
_ => return Err(format!("unknown or unimplemented day \"{day}\"").into()),
}
Ok(())