]> aoc.elinar.fr Git - aoc_2024/commitdiff
Day18 - part 2
authoralex <>
Wed, 18 Dec 2024 09:14:49 +0000 (10:14 +0100)
committeralex <>
Wed, 18 Dec 2024 09:14:49 +0000 (10:14 +0100)
src/day18.rs

index ebb8cab5bb71a10b7b72db4585fe678c79a85f61..f7bb33982492d471058fcea316790b5876ef2d13 100644 (file)
@@ -7,7 +7,7 @@ const WIDTH: isize = 70;
 
 struct Puzzle {
     mem: HashSet<(isize, isize)>,
-    corrupted: HashMap<(isize, isize), usize>,
+    corrupted: Vec<(isize, isize)>,
     height: isize,
     width: isize,
     start: (isize, isize),
@@ -16,13 +16,17 @@ struct Puzzle {
 
 impl Puzzle {
     pub fn new(input: &str, height: isize, width: isize) -> Self {
-        let mem: HashSet<(isize, isize)> = HashSet::new();
-        let corrupted: HashMap<(isize, isize), usize> = input.lines()
-            .enumerate()
-            .map(|(i, l)| {
+        let mut mem: HashSet<(isize, isize)> = HashSet::new();
+        (0..=height).for_each(|row| {
+            (0..=width).for_each(|col| {
+                mem.insert((row, col));
+            });
+        });
+        let corrupted: Vec<(isize, isize)> = input.lines()
+            .map(|l| {
                 let (x, y) = l.split_once(",").unwrap();
                 let (x, y) = (y.parse::<isize>().unwrap(), x.parse::<isize>().unwrap());
-                ((y, x), i)
+                (y, x)
             })
             .collect();
         let start = (0, 0);
@@ -30,16 +34,10 @@ impl Puzzle {
         Self { mem, corrupted, height, width, start, end }
     }
 
-    fn build_mem(&mut self, corrupted_size: usize) {
-        self.mem = HashSet::new();
-        (0..=self.height).for_each(|row| {
-            (0..=self.width).for_each(|col| {
-                if !self.corrupted.contains_key(&(row, col)) ||
-                    *self.corrupted.get(&(row,col)).unwrap() >= corrupted_size {
-                    self.mem.insert((row, col));
-                }
-            });
-        });
+    fn corrupt(&mut self, id: usize) {
+        if let Some(pos) = self.corrupted.get(id) {
+            self.mem.remove(&pos);
+        }
     }
 
     fn steps(&self) -> u32 {
@@ -74,30 +72,45 @@ impl Puzzle {
                 nb.cmp(&na)
             });
         }
-        *visited.get(&self.end).unwrap()
+        match visited.get(&self.end) {
+            Some(dst) => *dst,
+            None => 0
+        }
     }
 }
 
 fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
     println!("Running {} - part 1", get_day());
 
-    let corrupted_size = 1024;
     let mut puzzle = Puzzle::new(input, HEIGHT, WIDTH);
-    puzzle.build_mem(corrupted_size);
+    for i in 0..1024 {
+        puzzle.corrupt(i);
+    }
     Ok(puzzle.steps())
 }
 
-fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+fn run_part2(input: &str, height: isize, width: isize, corrupt_id: usize) -> Result<String, Box<dyn Error>> {
     println!("Running {} - part 2", get_day());
 
-    Ok(0)
+    let mut puzzle = Puzzle::new(input, height, width);
+    let mut id = 0;
+    while id < corrupt_id {
+        puzzle.corrupt(id);
+        id += 1;
+    }
+    while puzzle.steps() > 0 {
+        id += 1;
+        puzzle.corrupt(id);
+    }
+    let pos = puzzle.corrupted.get(id).unwrap();
+    Ok(format!("{},{}", pos.0, pos.1))
 }
 
 pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
     let res = run_part1(input)?;
     println!("{res}");
 
-    let res = run_part2(input)?;
+    let res = run_part2(input, HEIGHT, WIDTH, 1024)?;
     println!("{res}");
 
     Ok(())
@@ -142,13 +155,14 @@ mod tests {
     #[test]
     fn test_part1() {
         let mut puzzle = Puzzle::new(TEXT_INPUT, 6, 6);
-        let corrupted_size = 12;
-        puzzle.build_mem(corrupted_size);
+        for i in 0..12 {
+            puzzle.corrupt(i);
+        }
         assert_eq!(22, puzzle.steps());
     }
 
     #[test]
     fn test_part2() {
-        assert_eq!(0, run_part2(TEXT_INPUT).unwrap());
+        assert_eq!("6,1", run_part2(TEXT_INPUT, 6, 6, 12).unwrap());
     }
 }