feat: day 18

This commit is contained in:
Ashhhleyyy 2022-12-18 22:28:47 +00:00
parent 3660e45ae5
commit 4c86a3ddae
Signed by: ash
GPG key ID: 83B789081A0878FB
5 changed files with 2425 additions and 0 deletions

2176
.aoc-cache/18.txt Normal file

File diff suppressed because it is too large Load diff

106
Cargo.lock generated
View file

@ -35,6 +35,7 @@ dependencies = [
"lru-cache", "lru-cache",
"peg", "peg",
"petgraph", "petgraph",
"rayon",
"regex", "regex",
"time", "time",
"ureq", "ureq",
@ -135,6 +136,55 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "crossbeam-channel"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
[[package]]
name = "either"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]] [[package]]
name = "eyre" name = "eyre"
version = "0.6.8" version = "0.6.8"
@ -182,6 +232,15 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "idna" name = "idna"
version = "0.3.0" version = "0.3.0"
@ -259,6 +318,15 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.5.4" version = "0.5.4"
@ -277,6 +345,16 @@ dependencies = [
"adler", "adler",
] ]
[[package]]
name = "num_cpus"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.29.0" version = "0.29.0"
@ -365,6 +443,28 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rayon"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.7.0" version = "1.7.0"
@ -415,6 +515,12 @@ dependencies = [
"webpki", "webpki",
] ]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "sct" name = "sct"
version = "0.7.0" version = "0.7.0"

View file

@ -20,3 +20,4 @@ regex = "1.7.0"
petgraph = "0.6.2" petgraph = "0.6.2"
peg = "0.8.1" peg = "0.8.1"
lru-cache = "0.1.2" lru-cache = "0.1.2"
rayon = "1.6.1"

129
src/bin/day_18.rs Normal file
View file

@ -0,0 +1,129 @@
use std::{collections::{HashSet, HashMap}, ops::RangeInclusive};
use aoc_2022::prelude::*;
use rayon::prelude::*;
type Coord = (isize, isize, isize);
type Input = Vec<Coord>;
fn parse(s: &str) -> Result<Input> {
let mut coords = vec![];
for line in s.lines() {
let coord = ints(line);
let coord = (coord[0], coord[1], coord[2]);
coords.push(coord);
}
Ok(coords)
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
enum Face {
X,
Y,
Z,
}
#[aoc(day = 18, parse = parse, test_cases = ["day_18.txt"])]
fn day_18(input: Input) -> Result<()> {
// Part 1
let mut faces = HashSet::<(Face, Coord)>::new();
for cube in &input {
let cube_faces = [
(Face::X, *cube),
(Face::X, (cube.0 + 1, cube.1, cube.2)),
(Face::Y, *cube),
(Face::Y, (cube.0, cube.1 + 1, cube.2)),
(Face::Z, *cube),
(Face::Z, (cube.0, cube.1, cube.2 + 1)),
];
for face in cube_faces {
if faces.contains(&face) {
faces.remove(&face);
} else {
faces.insert(face);
}
}
}
println!("Part one: {}", faces.len());
// Part 2
let (x_range, y_range, z_range) = {
let min_x = input.iter().map(|c| c.0).min().unwrap();
let min_y = input.iter().map(|c| c.1).min().unwrap();
let min_z = input.iter().map(|c| c.2).min().unwrap();
let max_x = input.iter().map(|c| c.0).max().unwrap();
let max_y = input.iter().map(|c| c.1).max().unwrap();
let max_z = input.iter().map(|c| c.2).max().unwrap();
(min_x..=max_x, min_y..=max_y, min_z..=max_z)
};
let corrected_sa = faces.par_iter().filter(|(face, coord)| {
let other = match face {
Face::X => (coord.0 - 1, coord.1, coord.2),
Face::Y => (coord.0, coord.1 - 1, coord.2),
Face::Z => (coord.0, coord.1, coord.2 - 1),
};
let mut cache = HashMap::new();
can_reach_outside(&input, (&x_range, &y_range, &z_range), *coord, &HashSet::new(), &mut cache)
|| can_reach_outside(&input, (&x_range, &y_range, &z_range), other, &HashSet::new(), &mut cache)
}).count();
println!("Part 2: {corrected_sa}");
Ok(())
}
fn can_reach_outside(
input: &Input,
(x_range, y_range, z_range): (
&RangeInclusive<isize>,
&RangeInclusive<isize>,
&RangeInclusive<isize>,
),
position: Coord,
visited: &HashSet<Coord>,
cache: &mut HashMap<Coord, bool>,
) -> bool {
if let Some(result) = cache.get(&position) {
*result
} else {
let result = if x_range.contains(&position.0) && y_range.contains(&position.1) && z_range.contains(&position.2) {
if input.contains(&position) {
false
} else {
let mut visited = visited.clone();
visited.insert(position);
const DIRECTIONS: &[(isize, isize, isize)] = &[
( 1, 0, 0),
(-1, 0, 0),
( 0, 1, 0),
( 0, -1, 0),
( 0, 0, 1),
( 0, 0, -1),
];
let mut can_reach = false;
for direction in DIRECTIONS {
let new_position = (position.0 + direction.0, position.1 + direction.1, position.2 + direction.2);
if visited.contains(&new_position) {
continue;
}
if can_reach_outside(input, (x_range, y_range, z_range), new_position, &visited, cache) {
can_reach = true;
break;
}
}
can_reach
}
} else {
true
};
cache.insert(position, result);
result
}
}

13
test_cases/day_18.txt Normal file
View file

@ -0,0 +1,13 @@
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