diff options
Diffstat (limited to '2024/day10.rs')
| -rw-r--r-- | 2024/day10.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/2024/day10.rs b/2024/day10.rs new file mode 100644 index 0000000..7c8576d --- /dev/null +++ b/2024/day10.rs @@ -0,0 +1,103 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(unused_mut)] +use std::collections::HashSet; +use std::env; +use std::fs::File; +use std::io::Read; + +fn dfs(x0: i64, y0: i64, map: &Vec<Vec<i64>>, mut hs: HashSet<(i64, i64)>) -> HashSet<(i64, i64)> { + //println!("{} {}", x0, y0); + let h = map.len() as i64; + let w = map[0].len() as i64; + + let n = map[y0 as usize][x0 as usize]; + if n == 9 { + hs.insert((y0, x0)); + return hs; + } + + for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)] { + let x = x0 + dx as i64; + let y = y0 + dy as i64; + if (0 <= x) && (x < w) && (0 <= y) && (y < h) { + if map[y as usize][x as usize] == n + 1 { + hs = dfs(x, y, map, hs); + } + } + } + return hs; +} + +fn dfs2( + x0: i64, + y0: i64, + map: &Vec<Vec<i64>>, + mut path: Vec<(i64, i64)>, + mut hs: HashSet<Vec<(i64, i64)>>, +) -> HashSet<Vec<(i64, i64)>> { + //println!("{} {}", x0, y0); + let h = map.len() as i64; + let w = map[0].len() as i64; + + path.push((x0, y0)); + + let n = map[y0 as usize][x0 as usize]; + if n == 9 { + hs.insert(path); + return hs; + } + + for (dx, dy) in [(0, 1), (0, -1), (1, 0), (-1, 0)] { + let x = x0 + dx as i64; + let y = y0 + dy as i64; + if (0 <= x) && (x < w) && (0 <= y) && (y < h) { + if map[y as usize][x as usize] == n + 1 { + hs = dfs2(x, y, map, path.clone(), hs); + } + } + } + return hs; +} + +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 = content.trim_end().split("\n"); + + let mut trailheads: Vec<(i64, i64)> = Vec::new(); + let mut map: Vec<Vec<i64>> = Vec::new(); + for (y, line) in lines.enumerate() { + let mut l: Vec<i64> = Vec::new(); + for (x, c) in line.chars().enumerate() { + let n = c.to_digit(10).unwrap() as i64; + l.push(n); + if n == 0 { + trailheads.push((x as i64, y as i64)); + } + } + map.push(l); + } + + let mut res1 = 0; + let mut res2 = 0; + for (x0, y0) in trailheads { + let hs = dfs(x0, y0, &map, HashSet::new()); + res1 += hs.len(); + + let hs2 = dfs2(x0, y0, &map, Vec::new(), HashSet::new()); + res2 += hs2.len(); + } + + println!("res1: {}", res1); + println!("res2: {}", res2); + assert_eq!(res1, 607); + assert_eq!(res2, 1384); +} |
