]> aoc.elinar.fr Git - aoc_2023/commitdiff
Day21 - part 2 (préparatifs) main
authoralex <null>
Thu, 21 Dec 2023 21:24:31 +0000 (22:24 +0100)
committeralex <null>
Thu, 21 Dec 2023 22:25:38 +0000 (23:25 +0100)
* Ajout des exemples
* Suppression de la bordure de la carte (elle se répète à l'infini)

src/day21.rs

index 380671928ec509b24558881a3352a0e52b04c6d7..bca1425eafab8cb6ccf48a781c711e37e0ab762a 100644 (file)
@@ -4,17 +4,18 @@ use std::fs::File;
 
 use std::collections::VecDeque;
 
-const END_STEP: u32 = 64;
+const END_STEP_PART1: u32 = 64;
+const END_STEP_PART2: u32 = 26501365;
 
 pub fn run(input_file: &str) -> Result<(), Box<dyn Error>> {
     let mut f = File::open(input_file)?;
     let mut input = String::new();
     f.read_to_string(&mut input)?;
 
-    let res = run_part1(&input, END_STEP)?;
+    let res = run_part1(&input, END_STEP_PART1)?;
     println!("{res}");
 
-    let res = run_part2(&input)?;
+    let res = run_part2(&input, END_STEP_PART2)?;
     println!("{res}");
 
     Ok(())
@@ -36,27 +37,14 @@ impl Puzzle {
             .filter(|l| !l.is_empty())
             .enumerate()
             .for_each(|(i, l)| {
-                let mut c: Vec<char> = Vec::new();
-
-                c.push(' ');
-                c.append(&mut l.chars().collect::<Vec<char>>());
-                c.push(' ');
-
+                let c: Vec<char> = l.chars().collect();
                 match c.iter().position(|&a| a == 'S') {
-                    Some(p) => start = (i + 1, p),
+                    Some(p) => start = (i, p),
                     None => {},
                 }
-
-
-                if i == 0 {
-                    map.push(vec![' '; c.len()]);
-                }
                 map.push(c);
-
             });
 
-        map.push(vec![' '; map[0].len()]);
-
         let seen_at_step: Vec<Vec<u32>> = vec![
             vec![0 ; map[0].len()]
             ;
@@ -72,7 +60,7 @@ impl Puzzle {
 
     // une fois visitées les cases clignotes
     //   '.' -> 'O' -> '.' -> 'O'
-    pub fn travel(&mut self, end_step: u32) -> u32 {
+    pub fn travel(&mut self, end_step: u32) {
         let mut queue: VecDeque<(usize, usize)> = VecDeque::new();
         queue.push_back(self.start);
 
@@ -98,7 +86,13 @@ impl Puzzle {
             step += 1;
             queue = queue_next.clone();
         }
+    }
 
+    fn can_travel_to(&self, n: (usize, usize)) -> bool {
+        self.seen_at_step[n.0][n.1] == 0 && ['.', 'S'].contains(&self.map[n.0][n.1])
+    }
+
+    pub fn reachable(&self, end_step: u32) -> u32 {
         self.seen_at_step.iter()
             .map(|r| {
                 r.iter().filter(|&&s| {
@@ -108,10 +102,6 @@ impl Puzzle {
             })
             .sum::<usize>() as u32
     }
-
-    fn can_travel_to(&self, n: (usize, usize)) -> bool {
-        self.seen_at_step[n.0][n.1] == 0 && ['.', 'S'].contains(&self.map[n.0][n.1])
-    }
 }
 
 fn run_part1(input: &str, end_step: u32) -> Result<u32, Box<dyn Error>> {
@@ -119,13 +109,17 @@ fn run_part1(input: &str, end_step: u32) -> Result<u32, Box<dyn Error>> {
 
     let mut puzzle = Puzzle::new(input);
     //println!("{:?}", puzzle);
-    let res = puzzle.travel(end_step);
+    puzzle.travel(end_step);
+    let res = puzzle.reachable(end_step);
     Ok(res)
 }
 
-fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+fn run_part2(input: &str, end_step: u32) -> Result<u32, Box<dyn Error>> {
     println!("Running day21 - part 2");
-    let res = 0;
+
+    let mut puzzle = Puzzle::new(input);
+    puzzle.travel(end_step);
+    let res = puzzle.reachable(end_step);
     Ok(res)
 }
 
@@ -154,8 +148,33 @@ mod tests {
     }
 
     #[test]
-    fn day21_part2() {
-        let res = run_part2(TEXT_INPUT);
-        assert_eq!(0, res.unwrap());
+    fn day21_part2_example1() {
+        let res = run_part2(TEXT_INPUT, 10);
+        assert_eq!(50, res.unwrap());
+    }
+    #[test]
+    fn day21_part2_example2() {
+        let res = run_part2(TEXT_INPUT, 50);
+        assert_eq!(1594, res.unwrap());
+    }
+    #[test]
+    fn day21_part2_example3() {
+        let res = run_part2(TEXT_INPUT, 100);
+        assert_eq!(6536, res.unwrap());
+    }
+    #[test]
+    fn day21_part2_example4() {
+        let res = run_part2(TEXT_INPUT, 500);
+        assert_eq!(167004, res.unwrap());
+    }
+    #[test]
+    fn day21_part2_example5() {
+        let res = run_part2(TEXT_INPUT, 1000);
+        assert_eq!(668697, res.unwrap());
+    }
+    #[test]
+    fn day21_part2_example6() {
+        let res = run_part2(TEXT_INPUT, 5000);
+        assert_eq!(16733044, res.unwrap());
     }
 }