Advertisement
saaoijeefhiuh

2024 day 15

Dec 16th, 2024
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.33 KB | None | 0 0
  1. pub fn part_one(input: &str) -> Option<usize> {
  2.     let (igrid, imoves) = input.split_once("\n\n").unwrap();
  3.  
  4.     let (mut x, mut y) = (0, 0);
  5.  
  6.     let mut grid: Vec<Vec<char>> = igrid
  7.         .lines()
  8.         .enumerate()
  9.         .map(|(i, l)| {
  10.             l.chars()
  11.                 .enumerate()
  12.                 .map(|(j, c)| match c {
  13.                     '@' => {
  14.                         (x, y) = (j, i);
  15.                         '.'
  16.                     }
  17.                     'O' => 'O',
  18.                     '#' => '#',
  19.                     _ => '.',
  20.                 })
  21.                 .collect()
  22.         })
  23.         .collect();
  24.  
  25.     let (h, w) = (grid.len(), grid[0].len());
  26.  
  27.     // returns true if p can be moved by dir
  28.     fn push(
  29.         p: (usize, usize),
  30.         dir: (isize, isize),
  31.         grid: &Vec<Vec<char>>,
  32.         moves: &mut HashMap<(usize, usize), char>,
  33.     ) -> bool {
  34.         let n = (
  35.             p.0.wrapping_add_signed(dir.0),
  36.             p.1.wrapping_add_signed(dir.1),
  37.         );
  38.         let c = grid[n.0][n.1];
  39.         match c {
  40.             '.' => {
  41.                 moves.entry(p).or_insert('.');
  42.                 moves.insert(n, grid[p.0][p.1]);
  43.                 true
  44.             }
  45.             '#' => false,
  46.             '[' | ']' if dir.1 == 0 => {
  47.                 let nj = if c == '[' { n.1 + 1 } else { n.1 - 1 };
  48.                 moves.entry(p).or_insert('.');
  49.                 if push(n, dir, grid, moves) && push((n.0, nj), dir, grid, moves) {
  50.                     moves.insert(n, grid[p.0][p.1]);
  51.                     true
  52.                 } else {
  53.                     false
  54.                 }
  55.             }
  56.             'O' | _ => {
  57.                 if push(n, dir, grid, moves) {
  58.                     moves.insert(n, grid[p.0][p.1]);
  59.                     true
  60.                 } else {
  61.                     false
  62.                 }
  63.             }
  64.         }
  65.     }
  66.  
  67.     imoves.lines().flat_map(|l| l.chars()).for_each(|m| {
  68.         let dir = match m {
  69.             '^' => (-1, 0),
  70.             '>' => (0, 1),
  71.             'v' => (1, 0),
  72.             '<' | _ => (0, -1),
  73.         };
  74.         let mut moves: HashMap<(usize, usize), char> = HashMap::new();
  75.         if push((y, x), dir, &grid, &mut moves) {
  76.             moves.into_iter().for_each(|(d, c)| grid[d.0][d.1] = c);
  77.             (x, y) = (x.wrapping_add_signed(dir.1), y.wrapping_add_signed(dir.0));
  78.         }
  79.     });
  80.  
  81.     let g = grid.clone();
  82.     Some(
  83.         (0..h)
  84.             .flat_map(|i| (0..w).map(move |j| (i, j)))
  85.             .filter(|(i, j)| g[*i][*j] == 'O')
  86.             .map(|(i, j)| i * 100 + j)
  87.             .sum::<usize>(),
  88.     )
  89. }
  90.  
  91. pub fn part_two(input: &str) -> Option<usize> {
  92.     let (igrid, imoves) = input.split_once("\n\n").unwrap();
  93.  
  94.     let (mut x, mut y) = (0, 0);
  95.  
  96.     let mut grid: Vec<Vec<char>> = igrid
  97.         .lines()
  98.         .enumerate()
  99.         .map(|(i, l)| {
  100.             l.chars()
  101.                 .enumerate()
  102.                 .flat_map(|(j, c)| match c {
  103.                     '#' => ['#', '#'],
  104.                     'O' => ['[', ']'],
  105.                     '@' => {
  106.                         (x, y) = (j * 2, i);
  107.                         ['.', '.']
  108.                     }
  109.                     _ => ['.', '.'],
  110.                 })
  111.                 .collect()
  112.         })
  113.         .collect();
  114.  
  115.     let (h, w) = (grid.len(), grid[0].len());
  116.  
  117.     // returns true if p can be moved by dir
  118.     fn push(
  119.         p: (usize, usize),
  120.         dir: (isize, isize),
  121.         grid: &Vec<Vec<char>>,
  122.         moves: &mut HashMap<(usize, usize), char>,
  123.     ) -> bool {
  124.         let n = (
  125.             p.0.wrapping_add_signed(dir.0),
  126.             p.1.wrapping_add_signed(dir.1),
  127.         );
  128.         let c = grid[n.0][n.1];
  129.         match c {
  130.             '.' => {
  131.                 moves.entry(p).or_insert('.');
  132.                 moves.insert(n, grid[p.0][p.1]);
  133.                 true
  134.             }
  135.             '#' => false,
  136.             '[' | ']' if dir.1 == 0 => {
  137.                 let nj = if c == '[' { n.1 + 1 } else { n.1 - 1 };
  138.                 moves.entry(p).or_insert('.');
  139.                 if push(n, dir, grid, moves) && push((n.0, nj), dir, grid, moves) {
  140.                     moves.insert(n, grid[p.0][p.1]);
  141.                     true
  142.                 } else {
  143.                     false
  144.                 }
  145.             }
  146.             '[' | ']' | _ => {
  147.                 if push(n, dir, grid, moves) {
  148.                     moves.insert(n, grid[p.0][p.1]);
  149.                     true
  150.                 } else {
  151.                     false
  152.                 }
  153.             }
  154.         }
  155.     }
  156.  
  157.     imoves.lines().flat_map(|l| l.chars()).for_each(|m| {
  158.         let dir = match m {
  159.             '^' => (-1, 0),
  160.             '>' => (0, 1),
  161.             'v' => (1, 0),
  162.             '<' | _ => (0, -1),
  163.         };
  164.         let mut moves: HashMap<(usize, usize), char> = HashMap::new();
  165.         if push((y, x), dir, &grid, &mut moves) {
  166.             moves.into_iter().for_each(|(d, c)| grid[d.0][d.1] = c);
  167.             (x, y) = (x.wrapping_add_signed(dir.1), y.wrapping_add_signed(dir.0));
  168.         }
  169.     });
  170.  
  171.     let g = grid.clone();
  172.     Some(
  173.         (0..h)
  174.             .flat_map(|i| (0..w).map(move |j| (i, j)))
  175.             .filter(|(i, j)| g[*i][*j] == '[')
  176.             .map(|(i, j)| i * 100 + j)
  177.             .sum::<usize>(),
  178.     )
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement