mirror of
https://github.com/SebastianStork/advent-of-code.git
synced 2026-01-21 14:31:34 +01:00
Solve 2025 day 4 in rust
This commit is contained in:
parent
c7683b3600
commit
d8780f97a7
4 changed files with 182 additions and 3 deletions
7
2025/rust/day-04/Cargo.lock
generated
Normal file
7
2025/rust/day-04/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day-04"
|
||||||
|
version = "0.1.0"
|
||||||
6
2025/rust/day-04/Cargo.toml
Normal file
6
2025/rust/day-04/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "day-04"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
166
2025/rust/day-04/src/main.rs
Normal file
166
2025/rust/day-04/src/main.rs
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
use std::{cell::RefCell, fs, rc::Rc};
|
||||||
|
|
||||||
|
struct Roll {
|
||||||
|
neighbours: Vec<Rc<RefCell<Roll>>>,
|
||||||
|
deleted: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Roll {
|
||||||
|
fn new() -> Rc<RefCell<Roll>> {
|
||||||
|
Rc::new(RefCell::new(Roll {
|
||||||
|
neighbours: Vec::new(),
|
||||||
|
deleted: false,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_neighbour(this: &Rc<RefCell<Roll>>, neighbour: &Rc<RefCell<Roll>>) {
|
||||||
|
this.borrow_mut().neighbours.push(Rc::clone(neighbour));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_accessible(&self) -> bool {
|
||||||
|
self.neighbours
|
||||||
|
.iter()
|
||||||
|
.filter(|neighbour| !neighbour.borrow().deleted)
|
||||||
|
.count()
|
||||||
|
< 4
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete(this: &Rc<RefCell<Roll>>) {
|
||||||
|
if this.borrow().deleted {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.borrow_mut().deleted = true;
|
||||||
|
|
||||||
|
this.borrow()
|
||||||
|
.neighbours
|
||||||
|
.iter()
|
||||||
|
.filter(|neighbour| !neighbour.borrow().deleted)
|
||||||
|
.filter(|neighbour| neighbour.borrow().is_accessible())
|
||||||
|
.for_each(Roll::delete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let grid = parse_input(&fs::read_to_string("../../inputs/04.txt").unwrap());
|
||||||
|
let rolls = build_graph(grid);
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Number of accessible rolls: {}",
|
||||||
|
number_of_accessible_rolls(&rolls)
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"Number of removeable rolls: {}",
|
||||||
|
number_of_removeable_rolls(&rolls)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(contents: &str) -> Vec<Vec<Option<Rc<RefCell<Roll>>>>> {
|
||||||
|
contents
|
||||||
|
.trim()
|
||||||
|
.lines()
|
||||||
|
.map(|line: &str| {
|
||||||
|
line.bytes()
|
||||||
|
.map(|b| if b == b'@' { Some(Roll::new()) } else { None })
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_graph(grid: Vec<Vec<Option<Rc<RefCell<Roll>>>>>) -> Vec<Rc<RefCell<Roll>>> {
|
||||||
|
for (row_index, row) in grid.iter().enumerate() {
|
||||||
|
for (col_index, cell) in row.iter().enumerate() {
|
||||||
|
if let Some(roll) = cell {
|
||||||
|
for neighbour in get_neighbours(&grid, row_index, col_index) {
|
||||||
|
Roll::add_neighbour(roll, neighbour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grid.into_iter().flatten().flatten().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_neighbours(
|
||||||
|
grid: &[Vec<Option<Rc<RefCell<Roll>>>>],
|
||||||
|
row: usize,
|
||||||
|
col: usize,
|
||||||
|
) -> Vec<&Rc<RefCell<Roll>>> {
|
||||||
|
let offsets = [
|
||||||
|
(-1, -1),
|
||||||
|
(-1, 0),
|
||||||
|
(-1, 1),
|
||||||
|
(0, -1),
|
||||||
|
(0, 1),
|
||||||
|
(1, -1),
|
||||||
|
(1, 0),
|
||||||
|
(1, 1),
|
||||||
|
];
|
||||||
|
|
||||||
|
offsets
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(di, dj)| {
|
||||||
|
let (ni, nj) = (row as i32 + di, col as i32 + dj);
|
||||||
|
grid.get(ni as usize)?.get(nj as usize)?.as_ref()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn number_of_accessible_rolls(rolls: &[Rc<RefCell<Roll>>]) -> usize {
|
||||||
|
rolls
|
||||||
|
.iter()
|
||||||
|
.filter(|roll| roll.borrow().is_accessible())
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn number_of_removeable_rolls(rolls: &[Rc<RefCell<Roll>>]) -> usize {
|
||||||
|
loop {
|
||||||
|
let deleted_any = rolls
|
||||||
|
.iter()
|
||||||
|
.filter(|roll| !roll.borrow().deleted)
|
||||||
|
.filter(|roll| roll.borrow().is_accessible())
|
||||||
|
.inspect(|roll| Roll::delete(roll))
|
||||||
|
.count()
|
||||||
|
> 0;
|
||||||
|
|
||||||
|
if !deleted_any {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rolls.iter().filter(|roll| roll.borrow().deleted).count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const TEST_INPUT: &str = "
|
||||||
|
..@@.@@@@.
|
||||||
|
@@@.@.@.@@
|
||||||
|
@@@@@.@.@@
|
||||||
|
@.@@@@..@.
|
||||||
|
@@.@@@@.@@
|
||||||
|
.@@@@@@@.@
|
||||||
|
.@.@.@.@@@
|
||||||
|
@.@@@.@@@@
|
||||||
|
.@@@@@@@@.
|
||||||
|
@.@.@@@.@.
|
||||||
|
";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part1() {
|
||||||
|
assert_eq!(
|
||||||
|
number_of_accessible_rolls(&build_graph(parse_input(TEST_INPUT))),
|
||||||
|
13
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_part2() {
|
||||||
|
assert_eq!(
|
||||||
|
number_of_removeable_rolls(&build_graph(parse_input(TEST_INPUT))),
|
||||||
|
43
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -3,10 +3,10 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1764767558,
|
"lastModified": 1764840758,
|
||||||
"narHash": "sha256-AqEynDX4eu61liwLdGPzk0b6J9sE+dKWSpxfO+mZpBc=",
|
"narHash": "sha256-GTN8SBnhvv6t2oDS1H85xcYAhafy8mpUQWSrCErhtgw=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "a1a4c48fcc3eddac81d35ce2030c887ac38f4002",
|
"rev": "415a59297c64d0448d22975ca5ad3d8ef064c9f0",
|
||||||
"shallow": true,
|
"shallow": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@github.com/SebastianStork/advent-of-code-inputs.git"
|
"url": "ssh://git@github.com/SebastianStork/advent-of-code-inputs.git"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue