diff --git a/Cargo.lock b/Cargo.lock index 4d79e4e..ee9c375 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -340,6 +340,16 @@ dependencies = [ "nom", ] +[[package]] +name = "day21" +version = "0.1.0" +dependencies = [ + "aoc", + "color-eyre", + "nom", + "sqrid 0.0.23", +] + [[package]] name = "either" version = "1.9.0" diff --git a/Cargo.toml b/Cargo.toml index 849594f..3912780 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,5 +22,6 @@ members = [ "day17", "day18", "day20", + "day21", ] diff --git a/day21/Cargo.toml b/day21/Cargo.toml new file mode 100644 index 0000000..1a8e83e --- /dev/null +++ b/day21/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day21" +version = "0.1.0" +edition = "2021" + +[dependencies] +aoc = { path = "../aoc" } +color-eyre = "0.6.2" +nom = "7.1.3" +sqrid = "0.0.23" diff --git a/day21/input.txt b/day21/input.txt new file mode 100644 index 0000000..8307334 --- /dev/null +++ b/day21/input.txt @@ -0,0 +1,131 @@ +................................................................................................................................... +....#...#.......................#.#......###..#.............#................#.....#.....#.#...#.........#.#..........#......#..... +...#.##.#...#.....................#.......#.......#....#...................#....#...........#.#...........#....#...#............... +.#........#.#................#.....#.....#.........#.......................#..#...#........#..#..........##............#........... +.....#.#.....#.....#..........#........#.........#...#..........................#....#.#......#....#.#####.................#.#..... +...........................#...........#...#..#...#...............#.......#......#.#......#.......#.......#.........#.........#.... +......#...#.....##.......................#.....................#..............#..#...##...#....#....##....##....#..#............... +..................#...........#.................................#..#.......................#....#.....#................#........... +.#....##......#.............#.#.....#...#..#...#.....#.......#.....#.#..........#..##..........#.........#......................... +...........#.......#.....#................#.....#..............................#.#....#...............#..........................#. +............#.#..............#.......#...................................................#......##....#.......#...##............... +...................#.#......#.....................#........##.#....#...#............#...................#.....##.....#..#.#..#...#. +..........#......#...#...#..#.................#..............#.....................#.........#.#........#.......#.#..............#. +......#.......#...#.#............#.....#.#...................#...........##.......................#...#...##......#..#......#...... +.#.............#.....#......#.....#.........#..............##..................................#..#..#.#........#.....#............ +......#...............#......#............................#.............##..#.........##.........#.#......#......#..............#.. +.........#..............#..................................#.................#..........##.......#........#........##............#. +.....#..........#.....#.#..................##..........#....#.....#...#...#..#........#.............##.......#.....#........##.##.. +......#........#.....................#................#......................#...........#...#......#...##......................... +..............#................#..#...................#...###...............................#.#..##........##......##...#.....#.... +....#...............##.....#.#........#..............#..#.......#..#..#........#............#..##....#......#.....###.............. +.#......................#..#...#....#...........#...#...............#........#............#...#.##....#................##....#...#. +......#.......#.#...#......##.....................#...............#......#.....................##.....#.#.....##.................#. +......##................#....#...#...#.............#..................#.........#...............#...........##.................#... +....#.....#...#.#....#....#.......#.#.........#...###........#.........#.....................#.....#.##...#..##......#...#......... +.................#....#...#....#.#......................#...........#.....#.....#.#.##........#..........#......#..#....#.......... +....#...........#.......#....................#.#...#.........#.............#..#..................##............#.#................. +...................#.#.......#...##............#....#...........#.......#........................#...........#.##....##....##...... +......#..#.#...#..............#...............................#.....#.#.............#..#............#........#..............#.#.... +..#....#...........#...##..##..#........#..#.....#....#...#...#...#....#.#............................#.#.#........................ +......#................#.#................#..#....##........#........#....#...#..#.#......#..........##....#...#......#.#.#...#..#. +...#.#..##..#......#......................#................#....................#............................##...#......#..#...... +....#...#.##...##.......#................#.#..#........#.#.............#............##.#..........................##......##....... +...#.........###.#.....#............#.........#................#..............#............................#......#.....#..#....... +...###....#.........................#..#...#............................#.....##..#..........#...........#.....#................#.. +.............##.....#...............#..........#.....#.............#..#...#..#........#.#.#.............#............#...........#. +.......#..........#..............#.......#..#........#.#...............#................#....#...............#..................... +.............#..#.....................##.....#.#...............................#..#..#..#....#...##............#..#......#......... +................#...#.#.............#............#...........................#...........##...#..#..........#.......#..#........#.. +.........#.#.........#...........#.........#..........#...........#.............#..........#..................#...#....#....#..#... +...#.#.....#...#...............#..#......#.......##........#..#......#..#.....#..........#...#.#.............#...#....#.....#...... +..#...#..##.....#............#.#......#...#................................#.##.............###....#................##....#......#. +...................................#.#...#.......#.....##....#.#......#..#.............#...........#..#........#.................#. +.......#..................#..#................#.........................#.................#..........#..#.....................#.... +..........#...#.##..................#......##..##......#......#......#..##.....#..............#....#.............#...#..##.#...#... +................#.........................#.......#...............#.......#..#....##...#......#....#................#............#. +..#....#..##.#...........#.........##..#..#..#.................##......#...##..................##....#...............#.#..##....... +......#......#...........#....#...#....#.#......................#...........#................#.........#.#..........#.#............ +.....#....#..#.......##....................#................#.......#...........#.......#..............#..................#........ +..#........#........#.#.....##........#..#.....#.....#......#......#.#............##....#..............#..............#...#........ +..#.##........................#..##.#.........#.....#...#............#..............#...#.........#...........#............##...... +...#........................#.#....##.#.......#.#.............#....#...#......#.....#.....#..#......#...##...............#......... +......#...........#.................#......#.#......#.......##.#.....#.....#..............#...................#..............#..... +.......#..............#..........#..........#...........#...#........................#..#....#............................#....#... +................#..#.......#....#..##............####....#..#...#................#..............#................................#. +...#..#............#..#........#.......#......#..##...............#..#.#...#......#.........#.................#.#...........#.#.... +..#...............#...#..........................#.#.......#..#..........#...#.......#..#....#.#..............................#..#. +...#................................#...#.....#...#........#.......#..#..#..............#...#.....#.......#........................ +............##.............#.......#...........#...##......#......#.................#.......###...........#......#...............#. +.......................#...###.........#.....#.................#....##..#............#...........##....#.........#.#..##........... +...........##.....................#....#..#....................#.....................#..........#.....##........#................#. +........#........#.....##........##.........##..#.#..................##..........##...#...##..............#......#................. +...................#.........#.##..#..#.#..#...........##................#.......#......#...#.#........#.#..#...................... +.................#..........##.............#.....#.......##..#..#.......##..##...............#..............#......#.##............ +............#....#.............##...#.....#..................###..#..#......#............#............##..............#....#....... +.................................................................S................................................................. +............#......#....#........#..#..#.#..................#..#......#................#...........#.#..#....#......#..#.....#..... +................#.......................#...##.........#...............#.#...................##.........#....#..#...........#...... +...........#..##..#...........#........##...........#..##..#..#..........#......#..........#....#..#........#.........##........... +.........##..#...#.............#....#...........#...#...#......#..#...............#........#..............#.#....#................. +.#............................#..............#....##.....#..#..#............#.#....#..#......#.....#........#.....#................ +...................#...#...........#............#.....##........#....#....#..#....#.........#.#....#.#.....##..#..#....#........... +................#.#...#....#.#....##..#..##...#.......#.#............#.........................###.#.................##............ +.#.#.........................#.....................#.......................#.#...#..##...#..#.#.......#...............#.......#..#. +..............#...###...........#....#..#.................#..#......#.#........#.#...#...#..#..#...#.#..#.....................#.#.. +.....................................##...............#.#.......#.......#..........#......#.........#..#............#.............. +......................#..#.#.#...........#.##.....#...............#...#.........#.....##............##......................#....#. +...................#....#..#.#...#...#.....#.........#..#.......#...........#..#......................#.......#...........#........ +.....................#...#.....#.#......#....##..##.##.........#..........#...........###......#......#.......#...............#.... +..#.....................#..............#.#..#............#.....#.........#.#..............#................................#....... +.#........#...........##...........................#........#......##............#......#......#......#............................ +...........#...................#...##......#...........#...................#...................#.#......#.............#..#...#..... +..........#..........##........##..#.#....#.....#...........##.......#...........#.......##.#........#...#............#..........#. +.........#...........................#...#.##...........#.............##....#...#...#.............#.....#...#.........#............ +..#.....#...........................#....#.................#..#....................##..#.##.##....#......#..................#...... +.....##...................#......#.#..#.............#........#......#..#.........................#....................#....#...#... +.#...................................#....#........#...#.#...#...........#.#.......#..#..#.......##.#...................#....#.#.#. +.#......#....#....#........................#....................#...#..#...#..#...........#......#..#.............................. +..........#.......#..........#.........##...##.....#.......#....#..........#..#......#..................................##......... +...#...........#...............#.#....##......#.....................#....#..........##..#..##....##.#.........#......#.......#..... +.#.................#...........#......#...#........#.........#.##..............#.......#...#.#...#...#..........#..#.#............. +.....#..#...#...#...................#...#..#..#.......#..#................#............#......#...................##..#..........#. +......#.......#...#..............#.##.....#..#........#....#..........#..###...................................#............#...... +..#..........#...#..##..#...........##.........##....#..#...#..........#.##.......#.......#..#..#............#.#...#.......##..#... +..#..#....#..##........##...........#.#..................#......#.#.#........#..........#.................................#..#..... +.................#...........................#..#....................#..#.#.#..#....#....#..............#....###.....#...#..##.#... +......#.....#.........#.......................##.....#.......#.#..##....#.....#....#...##...#..#..........#....#..#................ +..........#........##...........................#.#..........#................#.....#.#...##.......................#.......#..#.... +.........#.....#...........#...........................................................................#.....#...............#..... +.................#.....#..................#...#....#.#............#..##..........#......#.##.............###......#..........#..... +.#...................................................#..#..#.#........#...............#....................#.............#..#...... +..#..#......#..#........#..#..............##...........#.#........#.........#..#....................................#.....#........ +.#.....#..#.#..##....#...#......................#..........###.#..##.......#.........................#....#........#..#............ +..#.......#.#.......#........#.#.............#..........#.........#...#.....................................#........#.##.......#.. +...#......#.#......##.##......##.#...........##....#.....#......................#...............#.....##.............#..........#.. +.#.#....#...................................##.................#.............##.#................#...#.#...#.............#.....###. +..#..........#.##.###....#...#.......#..............#.......#.................#.#....#..........#.#...#...#..#........#............ +.......##.........#....#....##..##............##.........#...........#...##.#.....##..........#.........#............#.#....#.##... +....#...###...........#......#.................#.....#.#.................#.................#......#.............................#.. +...#..#...................#..#....#...#.............#.......#.#.........###...#...................#....##..#...........#......#.... +.#...............#.............#..##............................#..........##.................#.#.#.##....#.......#.#...#..#....... +..#...........#.....................#..#...........#..#.##..#......####.........#..............................##........###.##.#.. +.......#.....#..........#.#.........................#...........#.....#...#....#..............#..........##.#................#..... +.#.....#....#...#....#..........#....................#................#....#...........#....#.....................##...#....#....#. +................##...#....#........#..##.............#............##.#....##............#........#.##............#.#.........#..... +......#.#.#.#....#........................#..................#.#........................#........#.#....................#.....#.#.. +......#..#.........#........#....#...#...#...#...............##.......#.#.............................................##...#....#.. +......#.#......................#....#..#....................#.......#................#..#..#.#..#...............#.........##.#..... +............#.....................###.......................##.....#.....#........#...#........#.........#..#........#.........#.#. +....#......#..#.................#........#..#...#.........#.....#.#.................#.............#..#.....#........#....#......... +.#..#......#..#.....................#.....#......#..............................#..#..................#..#..##...........#......... +...#.............#...........#...................#.#........#.....#............#............................#..#................... +.....#....#.........#..#.#..............#.#..#.##....#.......##..........................#....#...........#...............###...... +......#................#..#....................#.....#........................#.#....#.......#................#.............#...#.. +..........#...........#.........#.................#.........................#........#..#.............#......#..........#..#....... +.....#...#...................#.....#.........##..#.....................................#.....#.#....#........#...#..#....#......... +..#.#.......#...##..#........#..##...##.#...#...........#.........................#.....#........#..................#....#.....#.#. +.#.........................#.............#.......................................#..........##....#..#####.#.#.................#... +.#.#...........#.....#.##.....#...............#....#.....#.#.................#..#.....#...#...........#......#...#............#..#. +...#...........#..#............#.......#.#.........#..##................#.#.......#............#.................#.....##.......... +................................................................................................................................... diff --git a/day21/src/bin/day21a.rs b/day21/src/bin/day21a.rs new file mode 100644 index 0000000..668b8d1 --- /dev/null +++ b/day21/src/bin/day21a.rs @@ -0,0 +1,66 @@ +// Copyright (C) 2023 Leandro Lisboa Penz +// This file is subject to the terms and conditions defined in +// file 'LICENSE', which is part of this source code package. + +use day21::*; + +use std::collections::HashSet; + +pub use sqrid::Dir; +pub type Sqrid = sqrid::sqrid_create!(131, 131, false); +// pub type Sqrid = sqrid::sqrid_create!(11, 11, false); +pub type Pos = sqrid::pos_create!(Sqrid); +pub type Grid = sqrid::grid_create!(Sqrid, Cell); + +pub type GridDebug = sqrid::grid_create!(Sqrid, char); + +pub type Steps = i32; + +fn bfs( + size: u16, + grid: &Grid, + pos: Pos, + visited: &mut HashSet<(Pos, Steps)>, + end: &mut HashSet, + stepsleft: i32, +) { + if visited.contains(&(pos, stepsleft)) { + return; + } + if stepsleft == 0 { + end.insert(pos); + return; + } + for dir in Dir::iter::() { + let Ok(newpos) = pos + dir else { continue }; + let newpos_t = newpos.tuple(); + if newpos_t.0 >= size || newpos_t.1 >= size { + continue; + } + if grid[newpos] == Cell::Rock { + continue; + } + bfs(size, grid, newpos, visited, end, stepsleft - 1); + } + visited.insert((pos, stepsleft)); +} + +fn process(size: u16, steps: Steps, bufin: impl BufRead) -> Result { + let input = parser::parse(bufin)?; + let grid = Grid::try_from(input)?; + let start = Pos::iter().find(|p| grid[p] == Cell::Start).unwrap(); + let mut visited = HashSet::<(Pos, Steps)>::new(); + let mut end = HashSet::::new(); + bfs(size, &grid, start, &mut visited, &mut end, steps); + Ok(end.len()) +} + +#[test] +fn test() -> Result<()> { + assert_eq!(process(11, 6, EXAMPLE.as_bytes())?, 16); + Ok(()) +} + +fn main() -> Result<()> { + do_main(|| process(131, 64, stdin().lock())) +} diff --git a/day21/src/lib.rs b/day21/src/lib.rs new file mode 100644 index 0000000..95b609f --- /dev/null +++ b/day21/src/lib.rs @@ -0,0 +1,76 @@ +// Copyright (C) 2023 Leandro Lisboa Penz +// This file is subject to the terms and conditions defined in +// file 'LICENSE', which is part of this source code package. + +pub use aoc::*; + +pub const EXAMPLE: &str = "........... +.....###.#. +.###.##..#. +..#.#...#.. +....#.#.... +.##..S####. +.##..#...#. +.......##.. +.##.#.####. +.##..##.##. +........... +"; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum Cell { + #[default] + Empty, + Rock, + Start, +} + +impl TryFrom for Cell { + type Error = Report; + fn try_from(c: char) -> Result { + match c { + '.' => Ok(Cell::Empty), + '#' => Ok(Cell::Rock), + 'S' => Ok(Cell::Start), + other => Err(eyre!("invalid cell {}", other)), + } + } +} + +impl From for char { + fn from(c: Cell) -> Self { + match c { + Cell::Empty => '.', + Cell::Rock => '#', + Cell::Start => 'S', + } + } +} + +pub mod parser { + use aoc::parser::*; + + use super::*; + + fn cell(input: &str) -> IResult<&str, Cell> { + let (input, c) = character::one_of(r".#S")(input)?; + Ok((input, Cell::try_from(c).unwrap())) + } + + fn line(input: &str) -> IResult<&str, Vec> { + let (input, cells) = multi::many1(cell)(input)?; + let (input, _) = character::newline(input)?; + Ok((input, cells)) + } + + pub fn parse(mut bufin: impl BufRead) -> Result>> { + aoc::parse_with!(multi::many1(line), bufin) + } +} + +#[test] +fn test() -> Result<()> { + let input = parser::parse(EXAMPLE.as_bytes())?; + assert_eq!(input.len(), 11); + Ok(()) +}