Skip to content

Commit

Permalink
AoC 2023 Day 21 - rust
Browse files Browse the repository at this point in the history
  • Loading branch information
pareronia committed Dec 21, 2023
1 parent 2adddda commit 822aa75
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
| ---| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| python3 | [](src/main/python/AoC2023_01.py) | [](src/main/python/AoC2023_02.py) | [](src/main/python/AoC2023_03.py) | [](src/main/python/AoC2023_04.py) | [](src/main/python/AoC2023_05.py) | [](src/main/python/AoC2023_06.py) | [](src/main/python/AoC2023_07.py) | [](src/main/python/AoC2023_08.py) | [](src/main/python/AoC2023_09.py) | [](src/main/python/AoC2023_10.py) | [](src/main/python/AoC2023_11.py) | [](src/main/python/AoC2023_12.py) | [](src/main/python/AoC2023_13.py) | [](src/main/python/AoC2023_14.py) | [](src/main/python/AoC2023_15.py) | [](src/main/python/AoC2023_16.py) | [](src/main/python/AoC2023_17.py) | [](src/main/python/AoC2023_18.py) | [](src/main/python/AoC2023_19.py) | [](src/main/python/AoC2023_20.py) | [](src/main/python/AoC2023_21.py) | | | | |
| java | [](src/main/java/AoC2023_01.java) | [](src/main/java/AoC2023_02.java) | [](src/main/java/AoC2023_03.java) | [](src/main/java/AoC2023_04.java) | [](src/main/java/AoC2023_05.java) | [](src/main/java/AoC2023_06.java) | [](src/main/java/AoC2023_07.java) | [](src/main/java/AoC2023_08.java) | [](src/main/java/AoC2023_09.java) | [](src/main/java/AoC2023_10.java) | [](src/main/java/AoC2023_11.java) | [](src/main/java/AoC2023_12.java) | [](src/main/java/AoC2023_13.java) | [](src/main/java/AoC2023_14.java) | [](src/main/java/AoC2023_15.java) | [](src/main/java/AoC2023_16.java) | [](src/main/java/AoC2023_17.java) | [](src/main/java/AoC2023_18.java) | | [](src/main/java/AoC2023_20.java) | | | | | |
| rust | [](src/main/rust/AoC2023_01/src/main.rs) | [](src/main/rust/AoC2023_02/src/main.rs) | [](src/main/rust/AoC2023_03/src/main.rs) | [](src/main/rust/AoC2023_04/src/main.rs) | | [](src/main/rust/AoC2023_06/src/main.rs) | [](src/main/rust/AoC2023_07/src/main.rs) | [](src/main/rust/AoC2023_08/src/main.rs) | [](src/main/rust/AoC2023_09/src/main.rs) | | | | | | [](src/main/rust/AoC2023_15/src/main.rs) | [](src/main/rust/AoC2023_16/src/main.rs) | [](src/main/rust/AoC2023_17/src/main.rs) | [](src/main/rust/AoC2023_18/src/main.rs) | | | | | | | |
| rust | [](src/main/rust/AoC2023_01/src/main.rs) | [](src/main/rust/AoC2023_02/src/main.rs) | [](src/main/rust/AoC2023_03/src/main.rs) | [](src/main/rust/AoC2023_04/src/main.rs) | | [](src/main/rust/AoC2023_06/src/main.rs) | [](src/main/rust/AoC2023_07/src/main.rs) | [](src/main/rust/AoC2023_08/src/main.rs) | [](src/main/rust/AoC2023_09/src/main.rs) | | | | | | [](src/main/rust/AoC2023_15/src/main.rs) | [](src/main/rust/AoC2023_16/src/main.rs) | [](src/main/rust/AoC2023_17/src/main.rs) | [](src/main/rust/AoC2023_18/src/main.rs) | [](src/main/rust/AoC2023_19/src/main.rs) | | [](src/main/rust/AoC2023_21/src/main.rs) | | | | |
<!-- @END:ImplementationsTable:2023@ -->

## 2022
Expand Down
7 changes: 7 additions & 0 deletions src/main/rust/AoC2023_21/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "AoC2023_21"
version = "0.1.0"
edition = "2021"

[dependencies]
aoc = { path = "../aoc" }
106 changes: 106 additions & 0 deletions src/main/rust/AoC2023_21/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#![allow(non_snake_case)]

use std::collections::HashSet;

use aoc::{
grid::{Cell, CharGrid, Grid},
Puzzle,
};

struct AoC2023_21;

impl AoC2023_21 {
fn solve(&self, grid: &CharGrid, steps: &[usize]) -> Vec<u64> {
let w = grid.width() as i32;
let start = (w / 2, w / 2);
let mut plots: HashSet<(i32, i32)> = HashSet::new();
plots.insert(start);
let mut ans: Vec<u64> = vec![];
for i in 1..=*steps.iter().max().unwrap() {
let mut new_plots: HashSet<(i32, i32)> = HashSet::new();
for cell in &plots {
for (dr, dc) in [(0, 1), (0, -1), (1, 0), (-1, 0)] {
let rr = cell.0 + dr;
let cc = cell.1 + dc;
let wr = ((rr % w) + w) % w;
let wc = ((cc % w) + w) % w;
if 0 <= wr
&& wr < w
&& 0 <= wc
&& wc < w
&& grid.get(&Cell::at(wr as usize, wc as usize)) != '#'
{
new_plots.insert((rr, cc));
}
}
}
if steps.contains(&i) {
ans.push(new_plots.len() as u64)
}
plots = new_plots;
}
ans
}
}

impl aoc::Puzzle for AoC2023_21 {
type Input = CharGrid;
type Output1 = u64;
type Output2 = u64;

aoc::puzzle_year_day!(2023, 21);

fn parse_input(&self, lines: Vec<String>) -> CharGrid {
CharGrid::from(&lines.iter().map(AsRef::as_ref).collect())
}

fn part_1(&self, grid: &CharGrid) -> u64 {
self.solve(grid, &[64])[0]
}

fn part_2(&self, grid: &CharGrid) -> u64 {
let steps = 26_501_365;
let modulo = steps % grid.width();
let x: u64 = steps as u64 / grid.width() as u64;
let stepses: Vec<usize> =
(0..3).map(|i| i * grid.width() + modulo).collect();
let values = self.solve(grid, &stepses);
let a = (values[2] + values[0] - 2 * values[1]) / 2;
let b = values[1] - values[0] - a;
let c = values[0];
a * x * x + b * x + c
}

fn samples(&self) {
let grid = self.parse_input(TEST.lines().map(String::from).collect());
assert_eq!(self.solve(&grid, &[6, 10, 50, 100]), &[16, 50, 1594, 6536]);
}
}

fn main() {
AoC2023_21 {}.run(std::env::args());
}

const TEST: &str = "\
...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........
";

#[cfg(test)]
mod tests {
use super::*;

#[test]
pub fn samples() {
AoC2023_21 {}.samples();
}
}
15 changes: 15 additions & 0 deletions src/main/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 822aa75

Please sign in to comment.