1
0

day 15 part 2

This commit is contained in:
2024-12-15 13:20:15 +01:00
parent 24386b750b
commit c1abd8d8f8
2 changed files with 142 additions and 5 deletions

View File

@@ -1,6 +1,8 @@
use std::fs::read_to_string;
use std::{collections::HashSet, fs::read_to_string};
use crate::utils::grid::Grid;
use itertools::Itertools;
use crate::utils::grid::{Coord, Grid};
pub fn day_main() {
let input = read_to_string("input/day15.txt").unwrap();
@@ -44,8 +46,111 @@ fn part1(input: &str) -> RiddleResult {
.sum()
}
fn part2(_input: &str) -> RiddleResult {
0
fn part2(input: &str) -> RiddleResult {
let (grid, movements) = input.split_once("\n\n").unwrap();
let grid = grid
.lines()
.map(|line| {
{
line.chars().flat_map(|c| {
match c {
'.' => "..",
'@' => "@.",
'#' => "##",
'O' => "[]",
_ => panic!(),
}
.chars()
})
}
.join("")
})
.join("\n");
let mut grid = Grid::parse(grid.as_str());
let mut robot = grid.entries().find(|(_r, c)| **c == '@').unwrap().0;
let directions = |d| match d {
'^' => (0, -1),
'v' => (0, 1),
'<' => (-1, 0),
'>' => (1, 0),
_ => panic!(),
};
for m in movements.chars().filter(|c| *c != '\n') {
let dir = directions(m);
if let Some(tiles_to_move) = movable(robot, dir, &grid, false) {
let old = tiles_to_move
.iter()
.map(|tile| (*tile, grid[*tile]))
.collect_vec();
tiles_to_move.iter().for_each(|tile| grid[*tile] = '.');
old.into_iter()
.for_each(|(tile, c)| grid[(tile.0 + dir.0, tile.1 + dir.1)] = c);
robot = (robot.0 + dir.0, robot.1 + dir.1);
}
}
grid.entries()
.filter(|(_, c)| **c == '[')
.map(|((x, y), _)| y * 100 + x)
.sum()
}
fn movable(
from: (i64, i64),
dir: (i64, i64),
grid: &Grid<char>,
ignore_other_half: bool,
) -> Option<HashSet<Coord>> {
match grid[from] {
'.' => Some(HashSet::new()),
'@' => {
let next = movable((from.0 + dir.0, from.1 + dir.1), dir, grid, false);
next.map(|mut v| {
v.insert(from);
v
})
}
'[' => {
if dir.0 != 0 {
// sideway movement is "regular"
let next = movable((from.0 + dir.0, from.1 + dir.1), dir, grid, false);
next.map(|mut v| {
v.insert(from);
v
})
} else {
// up/down always means the other part of the crate has to move in parallel
let mut next1 = movable((from.0 + dir.0, from.1 + dir.1), dir, grid, false)?;
if !ignore_other_half {
let next2 = movable((from.0 + 1, from.1), dir, grid, true)?;
next1.extend(next2);
}
next1.insert(from);
Some(next1)
}
}
']' => {
if dir.0 != 0 {
// sideway movement is "regular"
let next = movable((from.0 + dir.0, from.1 + dir.1), dir, grid, false);
next.map(|mut v| {
v.insert(from);
v
})
} else {
// up/down always means the other part of the crate has to move in parallel
let mut next1 = movable((from.0 + dir.0, from.1 + dir.1), dir, grid, false)?;
if !ignore_other_half {
let next2 = movable((from.0 - 1, from.1), dir, grid, true)?;
next1.extend(next2);
}
next1.insert(from);
Some(next1)
}
}
_ => None,
}
}
#[cfg(test)]
@@ -63,6 +168,29 @@ mod test {
<^^>>>vv<v>>v<<";
const TEST_LARGE: &str = r"##########
#..O..O.O#
#......O.#
#.OO..O.O#
#..O@..O.#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^
";
#[test]
fn test1() {
assert_eq!(part1(TEST_INPUT), 2028);
@@ -70,6 +198,6 @@ mod test {
#[test]
fn test2() {
assert_eq!(part2(TEST_INPUT), 0);
assert_eq!(part2(TEST_LARGE), 9021);
}
}

View File

@@ -130,6 +130,15 @@ impl Grid<char> {
content,
}
}
pub fn print(&self) {
for line in &self.content.iter().chunks(self.content_width as usize) {
for c in line.into_iter() {
print!("{c}");
}
println!();
}
}
}
impl<T> Index<Coord> for Grid<T> {