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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test(n: usize, heights: &Vec<i64>) {
 | 
			
		||||
fn _test(n: usize, heights: &Vec<i64>) {
 | 
			
		||||
    if heights.len() % n == 0
 | 
			
		||||
    && heights[heights.len()/n-1]*n as i64+n as i64 == heights[heights.len()-1]+1 {
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    days::d17::solve()
 | 
			
		||||
    days::d18::solve()
 | 
			
		||||
    //_all_days()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue