diff options
| author | nekineki <nekineki@nekineki.net> | 2024-12-08 10:56:25 +0100 |
|---|---|---|
| committer | nekineki <nekineki@nekineki.net> | 2024-12-08 10:56:25 +0100 |
| commit | 88fa6b22f8546a5f10658eb84951fd744b67aa98 (patch) | |
| tree | f4ee903da1f418315d7cc5cad50cd69981381cb4 /2024/day08.rs | |
| parent | 15117b94410f53379957bd29d3953f7ed96ba774 (diff) | |
day08
Diffstat (limited to '2024/day08.rs')
| -rw-r--r-- | 2024/day08.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/2024/day08.rs b/2024/day08.rs new file mode 100644 index 0000000..30a1913 --- /dev/null +++ b/2024/day08.rs @@ -0,0 +1,99 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_mut)] +use itertools::Itertools; +use std::collections::HashMap; +use std::collections::HashSet; +use std::env; +use std::fs::File; +use std::io::Read; + +fn get_antinodes(a: (i32, i32), b: (i32, i32)) -> Vec<(i32, i32)> { + let mut ans = Vec::new(); + let (ax, ay) = (a.0, a.1); + let (bx, by) = (b.0, b.1); + let dx = bx - ax; + let dy = by - ay; + ans.push((bx + dx, by + dy)); + ans.push((ax - dx, ay - dy)); + return ans; +} + +fn bounded(min: i32, max: i32, val: i32) -> bool { + min <= val && val < max +} + +fn get_antinodes2(xmax: i32, ymax: i32, a: (i32, i32), b: (i32, i32)) -> Vec<(i32, i32)> { + let mut ans = Vec::new(); + let (ax, ay) = (a.0, a.1); + let (bx, by) = (b.0, b.1); + let dx = bx - ax; + let dy = by - ay; + + ans.push((ax, ay)); + ans.push((bx, by)); + + for n in 1.. { + let (ux, uy) = (bx + n * dx, by + n * dy); + if !bounded(0, xmax, ux) || !bounded(0, ymax, uy) { + break; + } + ans.push((ux, uy)); + } + + for n in 1.. { + let (ux, uy) = (ax - n * dx, ay - n * dy); + if !bounded(0, xmax, ux) || !bounded(0, ymax, uy) { + break; + } + ans.push((ux, uy)); + } + return ans; +} + +fn main() { + let args: Vec<String> = env::args().collect(); + let filename = if args.len() == 1 { + "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl" + } else { + args[1].clone() + }; + let mut f = File::open(filename).expect("cannot open file"); + let mut content = String::new(); + f.read_to_string(&mut content).expect("cannot read file"); + let lines: Vec<_> = content.trim_end().split("\n").collect(); + + let ymax = lines.len() as i32; + let xmax = lines[0].len() as i32; + + let mut hm: HashMap<char, Vec<(i32, i32)>> = HashMap::new(); + for (y, line) in lines.iter().enumerate() { + for (x, c) in line.chars().enumerate() { + if c != '.' { + hm.entry(c).or_default().push((x as i32, y as i32)); + } + } + } + + let mut antinodes: HashSet<(i32, i32)> = HashSet::new(); + let mut antinodes2: HashSet<(i32, i32)> = HashSet::new(); + for (key, val) in hm.clone().into_iter() { + for (a, b) in val.clone().into_iter().tuple_combinations() { + for (x, y) in get_antinodes(a, b) { + if bounded(0, xmax, x) && bounded(0, ymax, y) { + antinodes.insert((x, y)); + } + } + for (x, y) in get_antinodes2(xmax, ymax, a, b) { + antinodes2.insert((x, y)); + } + } + } + let res1 = antinodes.len(); + let res2 = antinodes2.len(); + + println!("res1: {}", res1); + println!("res2: {}", res2); + assert_eq!(res1, 293); + assert_eq!(res2, 934); +} |
