Day 18
This commit is contained in:
parent
b40956f6f7
commit
aef81474c0
5 changed files with 2904 additions and 2 deletions
2736
res/18/input.txt
Normal file
2736
res/18/input.txt
Normal file
File diff suppressed because it is too large
Load diff
13
res/18/test-input.txt
Normal file
13
res/18/test-input.txt
Normal 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
|
|
@ -109,7 +109,7 @@ pub fn solve() {
|
||||||
println!("Result 1: {}", highest_rock+1);
|
println!("Result 1: {}", highest_rock+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(n: usize, heights: &Vec<i64>) {
|
fn _test(n: usize, heights: &Vec<i64>) {
|
||||||
if heights.len() % n == 0
|
if heights.len() % n == 0
|
||||||
&& heights[heights.len()/n-1]*n as i64+n as i64 == heights[heights.len()-1]+1 {
|
&& heights[heights.len()/n-1]*n as i64+n as i64 == heights[heights.len()-1]+1 {
|
||||||
println!("{}: {}", n, heights.len()/n)
|
println!("{}: {}", n, heights.len()/n)
|
||||||
|
|
153
src/days/d18.rs
Normal file
153
src/days/d18.rs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
use std::{fs, collections::{HashMap, HashSet, VecDeque}};
|
||||||
|
|
||||||
|
pub fn solve() {
|
||||||
|
let path = "res/18/input.txt";
|
||||||
|
|
||||||
|
let contents = fs::read_to_string(path).expect("I/O error, wrong path?");
|
||||||
|
|
||||||
|
let coords: Vec<(usize,usize,usize)> = contents
|
||||||
|
.lines()
|
||||||
|
.filter(|line| *line != "")
|
||||||
|
.map(|line| {
|
||||||
|
let vals: Vec<&str> = line.split(",").collect();
|
||||||
|
(
|
||||||
|
vals[0].parse::<usize>().unwrap(),
|
||||||
|
vals[1].parse::<usize>().unwrap(),
|
||||||
|
vals[2].parse::<usize>().unwrap()
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let max: usize = coords
|
||||||
|
.iter()
|
||||||
|
.map(|coord|
|
||||||
|
coord.0.max(
|
||||||
|
coord.1.max(coord.2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.max()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let world_size = max as usize + 2;
|
||||||
|
|
||||||
|
// [x][y][z]
|
||||||
|
let mut world = vec![vec![vec![false;world_size];world_size];world_size];
|
||||||
|
|
||||||
|
for coord in coords.iter() {
|
||||||
|
world[coord.0 as usize][coord.1 as usize][coord.2 as usize] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// task 1 - count surfaces
|
||||||
|
let mut surfaces: u32 = 0;
|
||||||
|
|
||||||
|
let mut surface_blocks = HashMap::<(usize,usize,usize), usize>::new();
|
||||||
|
|
||||||
|
for (x1,y1,z1) in coords.iter() {
|
||||||
|
let (x,y,z) = (*x1 as usize, *y1 as usize, *z1 as usize);
|
||||||
|
// x-1
|
||||||
|
if x == 0 || !world[x-1][y][z] {
|
||||||
|
surfaces += 1;
|
||||||
|
if x != 0 { insert_or_increase((x-1,y,z), &mut surface_blocks) }
|
||||||
|
}
|
||||||
|
// x+1
|
||||||
|
if !world[x+1][y][z] {
|
||||||
|
surfaces += 1;
|
||||||
|
insert_or_increase((x+1,y,z), &mut surface_blocks)
|
||||||
|
}
|
||||||
|
// y-1
|
||||||
|
if y == 0 || !world[x][y-1][z] {
|
||||||
|
surfaces += 1;
|
||||||
|
if y != 0 { insert_or_increase((x,y-1,z), &mut surface_blocks) }
|
||||||
|
}
|
||||||
|
// y+1
|
||||||
|
if !world[x][y+1][z] {
|
||||||
|
surfaces += 1;
|
||||||
|
insert_or_increase((x,y+1,z), &mut surface_blocks)
|
||||||
|
}
|
||||||
|
// z-1
|
||||||
|
if z == 0 || !world[x][y][z-1] {
|
||||||
|
surfaces += 1;
|
||||||
|
if z != 0 { insert_or_increase((x,y,z-1), &mut surface_blocks) }
|
||||||
|
}
|
||||||
|
// z+1
|
||||||
|
if !world[x][y][z+1] {
|
||||||
|
surfaces += 1;
|
||||||
|
insert_or_increase((x,y,z+1), &mut surface_blocks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Result 1: {surfaces}");
|
||||||
|
|
||||||
|
// task 2 - find air bubbles by checking reachability between each surface block and a reference block outside with bfs
|
||||||
|
let reference_block: (usize, usize, usize) = (world_size-1, world_size-1, world_size-1);
|
||||||
|
for (block, block_surfaces) in surface_blocks.iter() {
|
||||||
|
if !bfs_reachable(*block, reference_block, &world) {
|
||||||
|
surfaces -= *block_surfaces as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Result 2: {surfaces}");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_or_increase(p: (usize,usize,usize), map: &mut HashMap::<(usize,usize,usize), usize>) {
|
||||||
|
if map.contains_key(&p) {
|
||||||
|
*map.get_mut(&p).unwrap() += 1;
|
||||||
|
} else {
|
||||||
|
map.insert(p, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bfs_reachable(s: (usize, usize, usize), e: (usize, usize, usize), world: &Vec<Vec<Vec<bool>>>) -> bool {
|
||||||
|
let mut queue = VecDeque::<(usize, usize, usize)>::new();
|
||||||
|
let mut seen_nodes = HashSet::<(usize, usize, usize)>::new();
|
||||||
|
|
||||||
|
seen_nodes.insert(s);
|
||||||
|
queue.push_back(s);
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let current = queue.pop_front().unwrap();
|
||||||
|
if current == e {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for adj in get_adjacents(current, world) {
|
||||||
|
if !seen_nodes.contains(&adj) {
|
||||||
|
seen_nodes.insert(adj);
|
||||||
|
queue.push_back(adj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_adjacents(p: (usize, usize, usize), world: &Vec<Vec<Vec<bool>>>) -> Vec<(usize,usize,usize)> {
|
||||||
|
let mut adj = Vec::<(usize,usize,usize)>::new();
|
||||||
|
let (x,y,z) = p;
|
||||||
|
|
||||||
|
if x > 0 && !world[x-1][y][z] {
|
||||||
|
adj.push((x-1,y,z))
|
||||||
|
}
|
||||||
|
// x+1
|
||||||
|
if x < world.len()-1 && !world[x+1][y][z] {
|
||||||
|
adj.push((x+1,y,z))
|
||||||
|
}
|
||||||
|
// y-1
|
||||||
|
if y > 0 && !world[x][y-1][z] {
|
||||||
|
adj.push((x,y-1,z))
|
||||||
|
}
|
||||||
|
// y+1
|
||||||
|
if y < world.len()-1 && !world[x][y+1][z] {
|
||||||
|
adj.push((x,y+1,z))
|
||||||
|
}
|
||||||
|
// z-1
|
||||||
|
if z > 0 && !world[x][y][z-1] {
|
||||||
|
adj.push((x,y,z-1))
|
||||||
|
}
|
||||||
|
// z+1
|
||||||
|
if z < world.len()-1 && !world[x][y][z+1] {
|
||||||
|
adj.push((x,y,z+1))
|
||||||
|
}
|
||||||
|
|
||||||
|
adj
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
pub mod days;
|
pub mod days;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
days::d17::solve()
|
days::d18::solve()
|
||||||
//_all_days()
|
//_all_days()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue