day 21
This commit is contained in:
parent
082eb03bc1
commit
0278599411
|
@ -1,2 +1,4 @@
|
|||
/target
|
||||
/erl_crash.dump
|
||||
/erl_crash.dump
|
||||
zig-out/
|
||||
zig-cache/
|
|
@ -206,6 +206,14 @@ dependencies = [
|
|||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day-21"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"indoc",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deprecate-until"
|
||||
version = "0.1.1"
|
||||
|
@ -448,9 +456,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
|||
|
||||
[[package]]
|
||||
name = "pathfinding"
|
||||
version = "4.4.0"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "752866d4511516a35883728309499db42696f388263586b70659a5461e641db5"
|
||||
checksum = "3ea07a6e677e47d6a84724d4fdf88b1e37fcb49ac94e236d7caeefd8fee75c8a"
|
||||
dependencies = [
|
||||
"deprecate-until",
|
||||
"fixedbitset",
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day-21"
|
||||
version = "0.0.0"
|
||||
edition = "2021"
|
||||
|
||||
[dev-dependencies]
|
||||
indoc.workspace = true
|
||||
|
||||
[dependencies]
|
||||
itertools.workspace = true
|
|
@ -0,0 +1,131 @@
|
|||
...................................................................................................................................
|
||||
....#.............#...............#.......#..........#..................##..........#.....#..................##...#...#..........#.
|
||||
...............#......#........#.......#........#.........................#.....#........#........#...#....#....#.........#....##..
|
||||
..#........#........#.##........#....#...#.....................................#................#.#...#..#....................#....
|
||||
...................#.............#........#.....#........#.........................#.......#...#.........#...........#...........#.
|
||||
...##.#....#...#.#..#....#.......##..#.....#..#..#......#.......#.........#.#.......#....#........#.....#.#...#................#...
|
||||
............#....#.........#.#..............##..................................#.#.......#.#..........#...#..#.#......##..#.......
|
||||
..................#...##............#.....#.....#.....#......................#..#.............................#....##..#...#.#.....
|
||||
............#.............#.........#........................##..............#.#....#.............#..........#.....#...............
|
||||
................#..#...##........#...#............#..................#.........#.....#..............#....#................#........
|
||||
.#...#...#..#.#...#............#....#..#.#.........#............#.#.#..#..................#.##....#.............#..................
|
||||
....#..#....#......#..#..##...#.#..#...##.........................#...................#..........#..#.......#...##.....#.....#.....
|
||||
....................#..........................##................................#.....................#................#.....#.##.
|
||||
..............#..............#..#..#.......#....#....................................#.........#..........#.#...............#.##...
|
||||
........#......#.#.........#.......#..........#..................................................................#........#..#..#..
|
||||
.................#.......##.......##......#..................#..#.......#....................#....#............#.......#.......#.#.
|
||||
.....##.......#......#...#.#....#..#.................#.#....#.....#.............................#..#.........#.#.................#.
|
||||
.......................#.....#...##...##..................................#....................##....##..........#..#..............
|
||||
.#.......#....##.....#........#..............................#.....#....#.....................#........#..#..#.......#.#....#....#.
|
||||
....#..#............#.........#...........................#.........##....#..#...................#..............#........#......##.
|
||||
......##.................#..#.....................#...........................#.........................#...................#......
|
||||
.....#...##.........#........#.##....###..................#........#..........................#.####................#.....#...#....
|
||||
.#....#...#........#....#.............#................#.................##...#....#................#..#...#.....#............#....
|
||||
....##.#.#.....#......#.......##.....#..........#........#..............#...#....#.................#.....#....#....................
|
||||
.....#..............#.##..#.......#..........##..........................#.#.........#..........#....##....#.........#.#...........
|
||||
.....#..#........#.#..........#...#.................#...........#.....#.........................#.#............#...................
|
||||
.......#...........#..........#......................#........................##.....##............#........#..................##..
|
||||
....#........................................#..#.....................#...#.#...#......................#...#....#................#.
|
||||
....#.##......#........#.....................#.........#...................#...#....#.#..............###..................###......
|
||||
..#...........#.....#....#..#.#............#...........#........#.....#.#................................#.......##....##..........
|
||||
...##.###.....................#............#.....#..#.#..............##..#.##..#.....#...................#.#......#....#...........
|
||||
.##....#............#....#.............#...#.#.............#..##.............#......................##.##..................#..#....
|
||||
...#.....##.........#..##..............#..#........##..#.#................#...#.#.#....#..................#..............#.........
|
||||
..........#....#.#.....#.................#...#............#.#......#...........#..........##..#...............#...#...##..#.#......
|
||||
..............#.....................#....#..#.##...#.......#.#..#.....#..................#................#........................
|
||||
......#.#.......#.....#...........##.................#......#........#.#........#..........#..##.........#...#.......#..#..........
|
||||
........................#..........#..#..................#...................#..#..##...##..#...................#.............#....
|
||||
...............#...#......................#....#...#..............##....#......#......#...#..#.....................................
|
||||
......#...#...###..#..#...................#...#.#............#......#...##....#.........#..#.....#.........#.#........##...........
|
||||
.#...#.........................##..##................#.....##.#...#........#.....#..#....##.........#..................#..#........
|
||||
..#......#.........#..........##..#......##.#................................................#.......#.........................#.#.
|
||||
......#....#..#.#..#.............#..............#.........#........#.....#.#..#......#.#.........................#..............#..
|
||||
.........................................#........#..................#...##.......#..........#........#..........#..#..............
|
||||
..#..........#............................#...#.....#....#..................#......................#.#..........#.##......#...#....
|
||||
...........................................#.....#..#....#........#.....#........#......#...#...................................#..
|
||||
..#..#...#.#..................#.#.............#..........#....#.....#......#......##.#..#...#.##....#....................#.....#...
|
||||
..#..##..........................#........#....#..........#........#..........#..#.#..............#..#......................#.#....
|
||||
....#...#.#.#..........#......................................#.......#...................##..#..#..................#.....#........
|
||||
............................#............##.#..............#.......#.#...#....#.........#....#......#........................#.....
|
||||
..#.........#...............#.......#....#..........#.....#.................#..#...##.#......................................#.....
|
||||
.......#...#.................#..................#......#....#..##...#.........#.#.#..........#...##..#.#...................#.......
|
||||
.........................#.............#....#...#.#.#....#.....#...............#........#.#...#..#..........#............#.........
|
||||
.......##.............##............#..###..#.#..#..##....#...#......##..#...#........#....#..#..........#..#..#..........#........
|
||||
..#..............#..##.......#...#........##.......................#..................#...........##........#.#..............#.....
|
||||
.#...#.............................#.#.......#....................#.......#..........#...................#....#...##...............
|
||||
..................####.#............###.....#.##..#...............#.............#..#..........#...............................#..#.
|
||||
.....................#....#.......#......#......#......#..................#..#....#..........#....#..............#..#..............
|
||||
.............#.#.##..#..#.....#.....##........##..#.#.........#......#..#.........##......#........#.........#...#...#.............
|
||||
.#..........#..#.........#...#..##.........#........###......#....##...........#......#.#......................#.....#.............
|
||||
..#.........##.#..#.#..........#.............................#.............##......#..#.............#.....#...#....#...............
|
||||
.#......................#.....................###..#.#.....#..........#..#.#.#....#.......#..#.........#...........................
|
||||
..........#......#....#..#....##..........#..........#.#...................#.................#....#.....#......#..........#........
|
||||
.........................#.....#.....#........................#.........#.#...#............................#.....#.................
|
||||
........#........#.........................##...............#.#.#......#......#......#..#.........#.....#.................#........
|
||||
...............##..........#...........................#.....#....#.....#.#...................#.............#...............#......
|
||||
.................................................................S.................................................................
|
||||
.................##...#....#..........#..##..##..........#......#..#..............##...#.#......#......#......#..#.......#.........
|
||||
..........#.........#.#...#..#....#.#.............#..#..#...........#.............#...........##.#...........#.......##............
|
||||
........#............#.#..........#..##.#.#...............#.....#......#...#...#....#......#........#.............#.......#........
|
||||
..........#...............#..#.................##.....#............#....###....#.............#................#...#................
|
||||
.#..............#.....##.#....#...#..#.##.......................#.#....#.......#.#............#........#.....#..##...##............
|
||||
.##.........#...................##.....#....#.......#.............##.......#...................#...........#.......#....#..........
|
||||
............#..#...#.....#....#...........#.#......#.#..#.........#.#....#..................##............#........................
|
||||
.............#..#...#....#......#......#......................#....#......###..........#..#.#..#...##....#..#......................
|
||||
...#.........#..........#..#.........................##...........#......#............#..#.#.....##............#..#.#........#..#..
|
||||
....#.#........##......................#.#.#.#..#.....#..#....##...#....##...#.#...#......#......................#.................
|
||||
.....##..................#..........#.....##.....##..........#.#..#.......#.#...#.........#.......#..........#....#..........#.#...
|
||||
...........................#..........#...#......#.#..#........#...#...............................#.#.#...#.....#..........#...##.
|
||||
.....................#..##.##.....#......#.........#..##...#...............#.#.#........#..#...#...........#...#...................
|
||||
..........#.........#..#.....#.......#.....###......#.....#.........#......#...............#.........#.........#...................
|
||||
.......##..#..............#.........#.....#.......#...##.###...........#.#..........##.........................................#...
|
||||
..#.....#..................#.#..........#..#..##....#...............#..............#.........##.........###.#...........#....##....
|
||||
.#....#.....#.................#...#..........#.........#....#..............#.........##......#...#..........#........#.#.......#...
|
||||
..............#.......................##.......##.......#..#.........#.....#....................................................#..
|
||||
...#..#......#.............#....##..........#.#.......#...............#................###...#....#......#.........#.....#.....#...
|
||||
....#..........#..........#..........#.....#..............#.......##......................#..#.#...............................#...
|
||||
.#......#.....................................##.#..........................#.....#.#..#.#..........##.......................#...#.
|
||||
......#........#.............#...........#.#............#.#.#...................#.##......#.#...................#....#..#..#.......
|
||||
.#.........##.....#.............#...........#.......#.......#.....##..###.....#...........#.......................#.#..............
|
||||
....##.........#.............................#.....##........#......#........#................#...#......................#.........
|
||||
..................#...............##...............##.....#..#.#........#.....#.....#........#...#..#.........#.#.....#......#.#...
|
||||
..................#.............##..#...............#....#.........##..#..........#......#....#.................##..#..#......#..#.
|
||||
.........###.......#................#....##.....#...#...........#.............................#...#................#...............
|
||||
...#......#...#...#...#...................#....#.#......#..#..#...#....#..#....................#..............#.................#..
|
||||
......................#.............##..#....#...#..............#...................#..#.......#..............###................#.
|
||||
..#........#.#............#..............#.......##......................#..............#..................#..#..#...........#.....
|
||||
.#........#..............................#..........................................#..........#.......#.............#.#.......#...
|
||||
.............#..#....#......#.......#.#.................................##...............................#....#......#.............
|
||||
.#.#...#...#....#...#......#................#..#.......#..#.##..............#...........#....#.......#............#....#.........#.
|
||||
...#.............#....#............................#........##.........##..........#..............................#.....#.......#..
|
||||
....#......#....#......#...................#.........#.......##.......................#..................###........###.......#....
|
||||
..........#...#......#........#..........#.........#.......#....#............#.....##......................#...........#..##..#.#..
|
||||
.###.#.##......#.#........................#.#..#...................#.......#....#................##...#..#...#..#..#.###....#......
|
||||
.....#.#......................................#.............#......#............................#..................................
|
||||
..................#...............##.................#.........................#.................#.......#..##.#..##.....#..#......
|
||||
...........#.........#.#...#....#.......................#.........#............#.#...#............##............#..................
|
||||
.....#........#.............#..#..................#..#......#...#.#.......#.....................#..................................
|
||||
..................#.#..............##..........#..........##....................................#.#............#.#.....#........#..
|
||||
.....#.#.##....#..............#..........................#......#....#...#.....................................#...#..#.#.....#....
|
||||
....#.#.........##.....................#...........................#......#.......#........#.#.#..#..#.......#....#..#......#...#..
|
||||
............#.......#.............#......#...............#......#.##.....#..#......................#....#.....#...........#..##....
|
||||
...#...#....#..#...##.......#.....#.....................##.....#..............#.............#...#....#..##.#....#........###..#....
|
||||
.....#..............#....#.......#..........................#..........................#..##.....#...##................##..........
|
||||
...#........#..#.#............##............#.........###....#.#.....#....#.............##................#.......#..##.......#.#..
|
||||
...........#.........#..#...........#...................#......#.....#.....................#...........#.....#.....................
|
||||
...#..#...##...............#..................#.............##......##...............#...#............#.........#..#...#.......#...
|
||||
......#...........#............##.#.#...#...............#..#......##...........................#...#..#.#.......#.....#.........##.
|
||||
...........#.#..#................#.......#......#............#..#.....#...............#....#.......#.#..#.#......#....#............
|
||||
...#..............................................................#................#.....#.........................................
|
||||
.................##.....................#.#....#..............#....................................#..............#.#..............
|
||||
.............##.............#..##..................#..............#............#.................#........................#.#......
|
||||
...........................#.....#..#..##.....##............#..#.......................#.....#..#.....#..#.....#........#....#.....
|
||||
..........#.................#........#.......................................#.#...#..###...###.#...........#...#..................
|
||||
..#....#.........#....#.........#....#.....#...................#............#....#.......#...#......#......#.#..........##..#......
|
||||
...#........................#..#...........#...##..........................###................#.#.......#..................#.......
|
||||
.......#.#............#.......#.....#.............................#.........#......#......................#........#...#.......#...
|
||||
.#.#..#.........................#..........#......................................#...........#..#...............#......##.........
|
||||
...#..............#......#.##....##.#...#..........##............................#.#.#........#.#........#....##.............#.....
|
||||
....................#...............#..#........#...........................................##..........#.#.....#....#.#...#.......
|
||||
.......................#........##..............#........#....................#.......#...#....#...........##........#....#.....#..
|
||||
...................................................................................................................................
|
|
@ -0,0 +1,115 @@
|
|||
use itertools::Itertools;
|
||||
|
||||
fn main() {
|
||||
println!("{}", part1(include_str!("./input.txt"), 64));
|
||||
}
|
||||
|
||||
fn part1(input: &str, steps: u32) -> usize {
|
||||
let map = input
|
||||
.lines()
|
||||
.map(|line| line.chars().map(Plot::from).collect())
|
||||
.collect::<Vec<Vec<_>>>();
|
||||
|
||||
let starting = map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(y, l)| {
|
||||
l.iter().enumerate().find_map(|(x, p)| {
|
||||
if p == &Plot::Starting {
|
||||
Some((x, y))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.expect("no starting plot");
|
||||
|
||||
let reachable = std::iter::successors(Some(vec![(starting, 0)]), |prev| {
|
||||
let next = prev
|
||||
.iter()
|
||||
.flat_map(|p| {
|
||||
successors(*p, &map)
|
||||
.into_iter()
|
||||
.filter(|(_, cur_steps)| *cur_steps <= steps)
|
||||
})
|
||||
.sorted()
|
||||
.dedup()
|
||||
.collect::<Vec<_>>();
|
||||
if next.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(next)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
reachable.last().expect("no last element").len()
|
||||
}
|
||||
|
||||
fn successors(
|
||||
((x, y), step_count): ((usize, usize), u32),
|
||||
map: &Vec<Vec<Plot>>,
|
||||
) -> Vec<((usize, usize), u32)> {
|
||||
let mut successors = vec![];
|
||||
if x > 0 && map[y][x - 1] != Plot::Stone {
|
||||
successors.push(((x - 1, y), step_count + 1));
|
||||
}
|
||||
if y > 0 && map[y - 1][x] != Plot::Stone {
|
||||
successors.push(((x, y - 1), step_count + 1));
|
||||
}
|
||||
if x < map[0].len() - 1 && map[y][x + 1] != Plot::Stone {
|
||||
successors.push(((x + 1, y), step_count + 1));
|
||||
}
|
||||
if y < map.len() - 1 && map[y + 1][x] != Plot::Stone {
|
||||
successors.push(((x, y + 1), step_count + 1));
|
||||
}
|
||||
successors
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
enum Plot {
|
||||
Starting,
|
||||
Garden,
|
||||
Stone,
|
||||
}
|
||||
impl From<char> for Plot {
|
||||
fn from(c: char) -> Self {
|
||||
match c {
|
||||
'.' => Plot::Garden,
|
||||
'#' => Plot::Stone,
|
||||
'S' => Plot::Starting,
|
||||
_ => panic!("Invalid plot"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!(
|
||||
part1(
|
||||
indoc!(
|
||||
"
|
||||
...........
|
||||
.....###.#.
|
||||
.###.##..#.
|
||||
..#.#...#..
|
||||
....#.#....
|
||||
.##..S####.
|
||||
.##..#...#.
|
||||
.......##..
|
||||
.##.#.####.
|
||||
.##..##.##.
|
||||
...........
|
||||
"
|
||||
),
|
||||
6
|
||||
),
|
||||
16
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,303 @@
|
|||
use itertools::Itertools;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
|
||||
fn main() {
|
||||
println!("{}", part2(include_str!("./input.txt"), 26501365));
|
||||
}
|
||||
|
||||
/// Assumptions for part 2:
|
||||
/// Line and column of the starting point are completely empty
|
||||
/// Borders are completely empty
|
||||
/// The garden is of odd size with the starting point in the middle
|
||||
/// The garden is a square
|
||||
/// The step count is a whole number of the gardens width plus half the width
|
||||
fn part2(input: &str, steps: u32) -> usize {
|
||||
/* IDEA:
|
||||
the inner repetitions of the garden have all the same amount of reachable plots,
|
||||
grouped by whether they are entered with an odd or even amount of steps.
|
||||
The corners of this diagonal square of reachable plots have the size of the
|
||||
garden minus one steps remaining and are different from each other.
|
||||
the small triangles have half the size of the garden minus one steps remaining
|
||||
and are entered from the corners.
|
||||
the big triangles have the size of the garden plus half the size of the garden
|
||||
of steps remaining and are also entered from the corners.
|
||||
*/
|
||||
|
||||
let map = input
|
||||
.lines()
|
||||
.map(|line| line.chars().map(Plot::from).collect())
|
||||
.collect::<Vec<Vec<_>>>();
|
||||
|
||||
assert!(map.len() == map[0].len(), "garden is not a square");
|
||||
assert!(
|
||||
steps as usize % map.len() == map.len() / 2,
|
||||
"steps is not a whole number of the gardens width plus half the width"
|
||||
);
|
||||
|
||||
let starting = map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(y, l)| {
|
||||
l.iter().enumerate().find_map(|(x, p)| {
|
||||
if p == &Plot::Starting {
|
||||
Some((x, y))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.expect("no starting plot");
|
||||
|
||||
assert!(
|
||||
starting.0 == map.len() / 2 && starting.1 == map.len() / 2,
|
||||
"starting point is not in the middle of the garden"
|
||||
);
|
||||
|
||||
let grid_width = steps as usize / map.len() - 1;
|
||||
|
||||
// round down to even number
|
||||
let odd_grids_amount = (grid_width / 2 * 2 + 1).pow(2);
|
||||
let even_grids_amount = ((grid_width + 1) / 2 * 2).pow(2);
|
||||
|
||||
let odd_points_each = fill(starting, map.len() as u32 * 2 + 1, &map);
|
||||
let even_points_each = fill(starting, map.len() as u32 * 2, &map);
|
||||
|
||||
let top_corner_points = fill((starting.0, map.len() - 1), map.len() as u32 - 1, &map);
|
||||
let right_corner_points = fill((0, starting.1), map.len() as u32 - 1, &map);
|
||||
let bottom_corner_points = fill((starting.0, 0), map.len() as u32 - 1, &map);
|
||||
let left_corner_points = fill((map.len() - 1, starting.1), map.len() as u32 - 1, &map);
|
||||
|
||||
let corner_points =
|
||||
top_corner_points + right_corner_points + bottom_corner_points + left_corner_points;
|
||||
|
||||
let small_top_right_points = fill((0, map.len() - 1), map.len() as u32 / 2 - 1, &map);
|
||||
let small_top_left_points = fill(
|
||||
(map.len() - 1, map.len() - 1),
|
||||
map.len() as u32 / 2 - 1,
|
||||
&map,
|
||||
);
|
||||
let small_bottom_right_points = fill((0, 0), map.len() as u32 / 2 - 1, &map);
|
||||
let small_bottom_left_points = fill((map.len() - 1, 0), map.len() as u32 / 2 - 1, &map);
|
||||
|
||||
let small_points = (small_top_right_points
|
||||
+ small_top_left_points
|
||||
+ small_bottom_right_points
|
||||
+ small_bottom_left_points)
|
||||
* (grid_width + 1);
|
||||
|
||||
let large_top_right_points = fill((0, map.len() - 1), map.len() as u32 * 3 / 2 - 1, &map);
|
||||
let large_top_left_points = fill(
|
||||
(map.len() - 1, map.len() - 1),
|
||||
map.len() as u32 * 3 / 2 - 1,
|
||||
&map,
|
||||
);
|
||||
let large_bottom_right_points = fill((0, 0), map.len() as u32 * 3 / 2 - 1, &map);
|
||||
let large_bottom_left_points = fill((map.len() - 1, 0), map.len() as u32 * 3 / 2 - 1, &map);
|
||||
|
||||
let large_points = (large_top_right_points
|
||||
+ large_top_left_points
|
||||
+ large_bottom_right_points
|
||||
+ large_bottom_left_points)
|
||||
* grid_width;
|
||||
|
||||
odd_grids_amount * odd_points_each
|
||||
+ even_grids_amount * even_points_each
|
||||
+ corner_points
|
||||
+ small_points
|
||||
+ large_points
|
||||
}
|
||||
|
||||
fn fill((starting_x, starting_y): (usize, usize), steps: u32, map: &Vec<Vec<Plot>>) -> usize {
|
||||
let mut ans = HashSet::new();
|
||||
let mut seen = HashSet::new();
|
||||
seen.insert((starting_x, starting_y));
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back(((starting_x, starting_y), steps));
|
||||
|
||||
while let Some(((x, y), remaining_steps)) = queue.pop_front() {
|
||||
if remaining_steps % 2 == 0 {
|
||||
ans.insert((x, y));
|
||||
}
|
||||
if remaining_steps == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
let directions = [
|
||||
Some((x + 1, y)),
|
||||
x.checked_sub(1).map(|x| (x, y)),
|
||||
Some((x, y + 1)),
|
||||
y.checked_sub(1).map(|y| (x, y)),
|
||||
];
|
||||
|
||||
for (nx, ny) in directions.into_iter().flatten() {
|
||||
if ny >= map.len()
|
||||
|| nx >= map[0].len()
|
||||
|| seen.contains(&(nx, ny))
|
||||
|| map[ny][nx] == Plot::Stone
|
||||
{
|
||||
continue;
|
||||
}
|
||||
seen.insert((nx, ny));
|
||||
queue.push_back(((nx, ny), remaining_steps - 1))
|
||||
}
|
||||
}
|
||||
|
||||
ans.len()
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
enum Plot {
|
||||
Starting,
|
||||
Garden,
|
||||
Stone,
|
||||
}
|
||||
impl From<char> for Plot {
|
||||
fn from(c: char) -> Self {
|
||||
match c {
|
||||
'.' => Plot::Garden,
|
||||
'#' => Plot::Stone,
|
||||
'S' => Plot::Starting,
|
||||
_ => panic!("Invalid plot"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
/// Bruteforce
|
||||
/// Takes too long
|
||||
fn part2_bruteforce(input: &str, steps: u32) -> usize {
|
||||
let map = input
|
||||
.lines()
|
||||
.map(|line| line.chars().map(Plot::from).collect())
|
||||
.collect::<Vec<Vec<_>>>();
|
||||
|
||||
let starting = map
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(y, l)| {
|
||||
l.iter().enumerate().find_map(|(x, p)| {
|
||||
if p == &Plot::Starting {
|
||||
Some((x as i128, y as i128))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.expect("no starting plot");
|
||||
|
||||
let mut visited = HashSet::new();
|
||||
visited.insert(starting);
|
||||
let mut new = HashSet::new();
|
||||
new.insert(starting);
|
||||
let mut cache = HashMap::new();
|
||||
cache.insert(0, 1);
|
||||
|
||||
let reachable = std::iter::successors(Some(vec![(starting, 0)]), |prev| {
|
||||
let next = prev
|
||||
.iter()
|
||||
.flat_map(|p| {
|
||||
successors(*p, &map)
|
||||
.into_iter()
|
||||
.filter(|(_, cur_steps)| *cur_steps <= steps)
|
||||
})
|
||||
.sorted()
|
||||
.dedup()
|
||||
.collect::<Vec<_>>();
|
||||
if next.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(next)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
reachable.last().expect("no last element").len()
|
||||
}
|
||||
|
||||
fn successors(
|
||||
((x, y), step_count): ((i128, i128), u32),
|
||||
map: &Vec<Vec<Plot>>,
|
||||
) -> Vec<((i128, i128), u32)> {
|
||||
let height = map.len();
|
||||
let width = map[0].len();
|
||||
let ux = (x.rem_euclid(width as i128)) as usize;
|
||||
let uy = (y.rem_euclid(height as i128)) as usize;
|
||||
let mut successors = vec![];
|
||||
if (ux > 0 && map[uy][ux - 1] != Plot::Stone) || (ux == 0 && map[uy][width - 1] != Plot::Stone)
|
||||
{
|
||||
successors.push(((x - 1, y), step_count + 1));
|
||||
}
|
||||
if (uy > 0 && map[uy - 1][ux] != Plot::Stone) || (uy == 0 && map[height - 1][ux] != Plot::Stone)
|
||||
{
|
||||
successors.push(((x, y - 1), step_count + 1));
|
||||
}
|
||||
if (ux < width - 1 && map[uy][ux + 1] != Plot::Stone)
|
||||
|| (ux == width - 1 && map[uy][0] != Plot::Stone)
|
||||
{
|
||||
successors.push(((x + 1, y), step_count + 1));
|
||||
}
|
||||
if (uy < height - 1 && map[uy + 1][ux] != Plot::Stone)
|
||||
|| (uy == height - 1 && map[0][ux] != Plot::Stone)
|
||||
{
|
||||
successors.push(((x, y + 1), step_count + 1));
|
||||
}
|
||||
successors
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use indoc::indoc;
|
||||
|
||||
const INPUT: &str = indoc!(
|
||||
"
|
||||
...........
|
||||
.....###.#.
|
||||
.###.##..#.
|
||||
..#.#...#..
|
||||
....#.#....
|
||||
.##..S####.
|
||||
.##..#...#.
|
||||
.......##..
|
||||
.##.#.####.
|
||||
.##..##.##.
|
||||
...........
|
||||
"
|
||||
);
|
||||
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_6() {
|
||||
assert_eq!(part2(INPUT, 6), 16);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_10() {
|
||||
assert_eq!(part2(INPUT, 10), 50);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_50() {
|
||||
assert_eq!(part2(INPUT, 50), 1594);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_100() {
|
||||
assert_eq!(part2(INPUT, 100), 6536);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_500() {
|
||||
assert_eq!(part2(INPUT, 500), 167004);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_1000() {
|
||||
assert_eq!(part2(INPUT, 1000), 668697);
|
||||
}
|
||||
#[test]
|
||||
#[ignore = "not working because of assumptions"]
|
||||
fn test_part2_5000() {
|
||||
assert_eq!(part2(INPUT, 5000), 16733044);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue