Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pub fn part_one(input: &str) -> Option<usize> {
- let (igrid, imoves) = input.split_once("\n\n").unwrap();
- let (mut x, mut y) = (0, 0);
- let mut grid: Vec<Vec<char>> = igrid
- .lines()
- .enumerate()
- .map(|(i, l)| {
- l.chars()
- .enumerate()
- .map(|(j, c)| match c {
- '@' => {
- (x, y) = (j, i);
- '.'
- }
- 'O' => 'O',
- '#' => '#',
- _ => '.',
- })
- .collect()
- })
- .collect();
- let (h, w) = (grid.len(), grid[0].len());
- // returns true if p can be moved by dir
- fn push(
- p: (usize, usize),
- dir: (isize, isize),
- grid: &Vec<Vec<char>>,
- moves: &mut HashMap<(usize, usize), char>,
- ) -> bool {
- let n = (
- p.0.wrapping_add_signed(dir.0),
- p.1.wrapping_add_signed(dir.1),
- );
- let c = grid[n.0][n.1];
- match c {
- '.' => {
- moves.entry(p).or_insert('.');
- moves.insert(n, grid[p.0][p.1]);
- true
- }
- '#' => false,
- '[' | ']' if dir.1 == 0 => {
- let nj = if c == '[' { n.1 + 1 } else { n.1 - 1 };
- moves.entry(p).or_insert('.');
- if push(n, dir, grid, moves) && push((n.0, nj), dir, grid, moves) {
- moves.insert(n, grid[p.0][p.1]);
- true
- } else {
- false
- }
- }
- 'O' | _ => {
- if push(n, dir, grid, moves) {
- moves.insert(n, grid[p.0][p.1]);
- true
- } else {
- false
- }
- }
- }
- }
- imoves.lines().flat_map(|l| l.chars()).for_each(|m| {
- let dir = match m {
- '^' => (-1, 0),
- '>' => (0, 1),
- 'v' => (1, 0),
- '<' | _ => (0, -1),
- };
- let mut moves: HashMap<(usize, usize), char> = HashMap::new();
- if push((y, x), dir, &grid, &mut moves) {
- moves.into_iter().for_each(|(d, c)| grid[d.0][d.1] = c);
- (x, y) = (x.wrapping_add_signed(dir.1), y.wrapping_add_signed(dir.0));
- }
- });
- let g = grid.clone();
- Some(
- (0..h)
- .flat_map(|i| (0..w).map(move |j| (i, j)))
- .filter(|(i, j)| g[*i][*j] == 'O')
- .map(|(i, j)| i * 100 + j)
- .sum::<usize>(),
- )
- }
- pub fn part_two(input: &str) -> Option<usize> {
- let (igrid, imoves) = input.split_once("\n\n").unwrap();
- let (mut x, mut y) = (0, 0);
- let mut grid: Vec<Vec<char>> = igrid
- .lines()
- .enumerate()
- .map(|(i, l)| {
- l.chars()
- .enumerate()
- .flat_map(|(j, c)| match c {
- '#' => ['#', '#'],
- 'O' => ['[', ']'],
- '@' => {
- (x, y) = (j * 2, i);
- ['.', '.']
- }
- _ => ['.', '.'],
- })
- .collect()
- })
- .collect();
- let (h, w) = (grid.len(), grid[0].len());
- // returns true if p can be moved by dir
- fn push(
- p: (usize, usize),
- dir: (isize, isize),
- grid: &Vec<Vec<char>>,
- moves: &mut HashMap<(usize, usize), char>,
- ) -> bool {
- let n = (
- p.0.wrapping_add_signed(dir.0),
- p.1.wrapping_add_signed(dir.1),
- );
- let c = grid[n.0][n.1];
- match c {
- '.' => {
- moves.entry(p).or_insert('.');
- moves.insert(n, grid[p.0][p.1]);
- true
- }
- '#' => false,
- '[' | ']' if dir.1 == 0 => {
- let nj = if c == '[' { n.1 + 1 } else { n.1 - 1 };
- moves.entry(p).or_insert('.');
- if push(n, dir, grid, moves) && push((n.0, nj), dir, grid, moves) {
- moves.insert(n, grid[p.0][p.1]);
- true
- } else {
- false
- }
- }
- '[' | ']' | _ => {
- if push(n, dir, grid, moves) {
- moves.insert(n, grid[p.0][p.1]);
- true
- } else {
- false
- }
- }
- }
- }
- imoves.lines().flat_map(|l| l.chars()).for_each(|m| {
- let dir = match m {
- '^' => (-1, 0),
- '>' => (0, 1),
- 'v' => (1, 0),
- '<' | _ => (0, -1),
- };
- let mut moves: HashMap<(usize, usize), char> = HashMap::new();
- if push((y, x), dir, &grid, &mut moves) {
- moves.into_iter().for_each(|(d, c)| grid[d.0][d.1] = c);
- (x, y) = (x.wrapping_add_signed(dir.1), y.wrapping_add_signed(dir.0));
- }
- });
- let g = grid.clone();
- Some(
- (0..h)
- .flat_map(|i| (0..w).map(move |j| (i, j)))
- .filter(|(i, j)| g[*i][*j] == '[')
- .map(|(i, j)| i * 100 + j)
- .sum::<usize>(),
- )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement