diff --git a/src/tasks/day22.rs b/src/tasks/day22.rs index 03a88fe..603db2e 100644 --- a/src/tasks/day22.rs +++ b/src/tasks/day22.rs @@ -1,32 +1,63 @@ +use crate::tasks::day22::Equipment::*; + pub fn task1() { - let depth: usize = 3879; - //let target: (usize, usize) = (8, 713); - const TARGET_X: usize = 8; - const TARGET_Y: usize = 713; + let cave = Cave::create(3879, Node(8, 713, Torch)); - let mut map: Vec> = Vec::with_capacity(TARGET_X + 1); - let mut inner_vec = Vec::with_capacity(TARGET_Y + 1); - inner_vec.resize(TARGET_Y + 1, 0); - map.resize(TARGET_X + 1, inner_vec); + println!("Sum of erosion indexes: {}", cave.erosion_sum()); +} - for x in 0..=TARGET_X { - for y in 0..=TARGET_Y { - let geo_index = match (x, y) { - (0, 0) => 0, - (TARGET_X, TARGET_Y) => 0, - (x, 0) => x * 16807, - (0, y) => y * 48271, - (x, y) => map[x - 1][y] * map[x][y - 1], - }; - let erosion_index = (geo_index + depth) % 20183; - map[x][y] = erosion_index; +#[derive(PartialEq)] +enum Equipment { + Torch, + Climbing, + Neither, +} + +struct Node(usize, usize, Equipment); + +struct Cave { + map: Vec>, + target: Node, +} + +impl Cave { + fn create(depth: usize, target: Node) -> Self { + if target.2 != Torch { + panic!("A valid target point needs the torch equipped"); } + let mut map: Vec> = Vec::with_capacity(target.0 + 1); + let mut inner_vec = Vec::with_capacity(target.1 + 1); + inner_vec.resize(target.1 + 1, 0); + map.resize(target.0 + 1, inner_vec); + + for x in 0..=target.0 { + for y in 0..=target.1 { + let geo_index = match (x, y) { + (0, 0) => 0, + _ if target.0 == x && target.1 == y => 0, + (x, 0) => x * 16807, + (0, y) => y * 48271, + (x, y) => map[x - 1][y] * map[x][y - 1], + }; + let erosion_index = (geo_index + depth) % 20183; + map[x][y] = erosion_index; + } + } + + Cave { map, target } } - // println!("{:?}", map); + fn erosion_sum(&self) -> usize { + (0..=self.target.0) + .map(|x| { + (0..=self.target.1) + .map(|y| self.field_type(x, y)) + .sum::() + }) + .sum() + } - let result: usize = (0..=TARGET_X) - .map(|x| (0..=TARGET_Y).map(|y| map[x][y] % 3).sum::()) - .sum(); - println!("Sum of erosion indexes: {}", result); + fn field_type(&self, x: usize, y: usize) -> usize { + self.map[x][y] % 3 + } }