day 15 part 2
This commit is contained in:
144
src/day15.rs
144
src/day15.rs
@@ -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() {
|
pub fn day_main() {
|
||||||
let input = read_to_string("input/day15.txt").unwrap();
|
let input = read_to_string("input/day15.txt").unwrap();
|
||||||
@@ -44,8 +46,117 @@ fn part1(input: &str) -> RiddleResult {
|
|||||||
.sum()
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(_input: &str) -> RiddleResult {
|
fn part2(input: &str) -> RiddleResult {
|
||||||
0
|
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());
|
||||||
|
|
||||||
|
// println!("Initial state:");
|
||||||
|
// grid.print();
|
||||||
|
// println!();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
// println!("Move {m}:");
|
||||||
|
// grid.print();
|
||||||
|
// println!();
|
||||||
|
}
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
@@ -63,6 +174,29 @@ mod test {
|
|||||||
|
|
||||||
<^^>>>vv<v>>v<<";
|
<^^>>>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]
|
#[test]
|
||||||
fn test1() {
|
fn test1() {
|
||||||
assert_eq!(part1(TEST_INPUT), 2028);
|
assert_eq!(part1(TEST_INPUT), 2028);
|
||||||
@@ -70,6 +204,6 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test2() {
|
fn test2() {
|
||||||
assert_eq!(part2(TEST_INPUT), 0);
|
assert_eq!(part2(TEST_LARGE), 9021);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,15 @@ impl Grid<char> {
|
|||||||
content,
|
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> {
|
impl<T> Index<Coord> for Grid<T> {
|
||||||
|
|||||||
Reference in New Issue
Block a user