Advertisement
Guest User

Untitled

a guest
Dec 20th, 2024
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.31 KB | None | 0 0
  1. use grid::Grid;
  2.  
  3. // # Algorithm outline:
  4. // 1. create grid of distances
  5. // 2. traverse, check each cell from -20,-20 to +20,+20
  6. //      a. check if xy distance is less than 20 picoseconds
  7. //      b. if dist < distance - 100, valid cheat
  8.  
  9. const  ADJACENTS: [(i32, i32); 4] = [
  10.     (0, -1),
  11.     (1, 0),
  12.     (0, 1),
  13.     (-1, 0),
  14. ];
  15.  
  16. const PICOSECONDS: i32 = 100;
  17.  
  18. fn main() {
  19.     let time = std::time::Instant::now();
  20.     let input: Vec<_> = include_str!("../input.txt").lines().collect();
  21.     let mut grid: Grid<char> = Grid::new(input.len(), input[0].len());
  22.     let mut end: Option<(i32, i32)> = None;
  23.  
  24.     for (y, row) in input.into_iter().enumerate() {
  25.         for (x, c) in row.chars().enumerate() {
  26.             grid[(y, x)] = c;
  27.  
  28.             if c == 'E' {
  29.                 end = Some((x as i32, y as i32));
  30.             }
  31.         }
  32.     }
  33.  
  34.     let end = end.unwrap();
  35.     let mut distances: Grid<Option<i32>> = Grid::new(grid.rows(), grid.cols());
  36.     distances.fill(None);
  37.     let mut cursor: (i32, i32);
  38.     let mut next = end.clone();
  39.     let mut distance = 0;
  40.  
  41.     'outer: loop {
  42.        cursor = next;
  43.  
  44.        distances[(cursor.1 as usize, cursor.0 as usize)] = Some(distance);
  45.        distance += 1;
  46.  
  47.        for (xd, yd) in ADJACENTS {
  48.            let x = cursor.0 + xd;
  49.            let y = cursor.1 + yd;
  50.            if let Some(cell) = grid.get(y, x) {
  51.                match cell {
  52.                    '#' => (),
  53.                    'S' => {
  54.                        distances[(y as usize, x as usize)] = Some(distance);
  55.                        break 'outer;
  56.                     },
  57.                     '.' => {
  58.                         grid[(y as usize, x as usize)] = 'O';
  59.                         next = (x, y);
  60.                     },
  61.                     'O' | 'E' => (),
  62.                     // 'S' => done = true,
  63.                     _ => unimplemented!()
  64.                 }
  65.             }
  66.         }
  67.     }
  68.  
  69.     let width = grid.cols();
  70.     let height = grid.rows();
  71.     let mut cheats = 0;
  72.  
  73.     for ((y, x), cell) in distances.indexed_iter() {
  74.         if let &Some(from_distance) = cell {
  75.             // No way to find a shortcut that saves more than PICOSECONDS
  76.             if from_distance < PICOSECONDS {
  77.                 continue;
  78.             }
  79.  
  80.             let top    = y.saturating_sub(20);
  81.             let left   = x.saturating_sub(20);
  82.             let bottom = (y + 20).max(height - 1);
  83.             let right  = (x + 20).max(width - 1);
  84.  
  85.             for ty in top..=bottom {
  86.                 for tx in left..=right {
  87.                     let pico = (x.abs_diff(tx) + y.abs_diff(ty)) as i32;
  88.                     if pico > 20 {
  89.                         continue;
  90.                     }
  91.  
  92.                     if let Some(&Some(to_distance)) = distances.get(ty, tx) {
  93.                         if to_distance <= from_distance - pico - PICOSECONDS {
  94.                             cheats += 1;
  95.                         }
  96.                     }
  97.                 }
  98.             }
  99.         }
  100.     }
  101.  
  102.     println!("Cheats: {}", cheats);
  103.     println!("Time elapsed: {:?}", time.elapsed());
  104.  
  105.     // let grid_out = grid.iter_rows()
  106.     //     .map(|row| row.into_iter().collect::<String>())
  107.     //     .collect::<Vec<String>>()
  108.     //     .join("\n");
  109.     // println!("Grid:\n{}", grid_out);
  110. }
  111.  
  112.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement