This commit is contained in:
2022-12-18 12:08:19 +01:00
parent 8b1c3ff175
commit 8cb4f331f1
5 changed files with 2264 additions and 0 deletions

2145
inputs/day18.txt Normal file

File diff suppressed because it is too large Load Diff

8
src/bin/day18_1.rs Normal file
View File

@@ -0,0 +1,8 @@
use std::fs;
use aoc2022::day18::process_part_1;
fn main() {
let file = fs::read_to_string("./inputs/day18.txt").unwrap();
println!("{}", process_part_1(&file));
}

8
src/bin/day18_2.rs Normal file
View File

@@ -0,0 +1,8 @@
use std::fs;
use aoc2022::day18::process_part_2;
fn main() {
let file = fs::read_to_string("./inputs/day18.txt").unwrap();
println!("{}", process_part_2(&file));
}

102
src/day18.rs Normal file
View File

@@ -0,0 +1,102 @@
use std::collections::HashSet;
use nom::character::complete;
use nom::character::complete::newline;
use nom::combinator::opt;
use nom::multi::fold_many1;
use nom::sequence::{preceded, terminated, tuple};
use nom::IResult;
pub fn sides((x, y, z): (i32, i32, i32)) -> [(i32, i32, i32); 6] {
[
(x + 1, y, z),
(x - 1, y, z),
(x, y + 1, z),
(x, y - 1, z),
(x, y, z + 1),
(x, y, z - 1),
]
}
pub fn process_part_1(input: &str) -> usize {
let drops = parse_input(input).unwrap().1;
drops
.iter()
.flat_map(|&v| sides(v))
.filter(|v| !drops.contains(v))
.count()
}
pub fn process_part_2(input: &str) -> usize {
let drops = parse_input(input).unwrap().1;
// Flood fill Bounding box so we don't go too far out of sanity, its a dumb bounding box though
let max = drops.iter().flat_map(|&(x, y, z)| [x, y, z]).max().unwrap() + 1;
let mut seen = HashSet::new();
let mut stack = vec![(0, 0, 0)];
while let Some(pos) = stack.pop() {
for (x, y, z) in sides(pos) {
if !drops.contains(&(x, y, z))
&& !seen.contains(&(x, y, z))
&& [x, y, z].iter().all(|&i| -1 <= i && i <= max)
{
seen.insert((x, y, z));
stack.push((x, y, z));
}
}
}
drops
.iter()
.flat_map(|&v| sides(v))
.filter(|v| seen.contains(v))
.count()
}
fn parse_input(input: &str) -> IResult<&str, HashSet<(i32, i32, i32)>> {
fold_many1(parse_line, HashSet::new, |mut set, v| {
set.insert(v);
set
})(input)
}
fn parse_line(input: &str) -> IResult<&str, (i32, i32, i32)> {
terminated(
tuple((
complete::i32,
preceded(complete::char(','), complete::i32),
preceded(complete::char(','), complete::i32),
)),
opt(newline),
)(input)
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = "2,2,2
1,2,2
3,2,2
2,1,2
2,3,2
2,2,1
2,2,3
2,2,4
2,2,6
1,2,5
3,2,5
2,1,5
2,3,5";
#[test]
fn day1() {
assert_eq!(process_part_1(INPUT), 64);
}
#[test]
fn day2() {
assert_eq!(process_part_2(INPUT), 58);
}
}

View File

@@ -18,3 +18,4 @@ pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
pub mod day18;