diff --git a/src/10part1.rs b/src/10part1.rs new file mode 100644 index 0000000..74f9bd6 --- /dev/null +++ b/src/10part1.rs @@ -0,0 +1,97 @@ +use std::{fs, collections::HashMap}; + +#[derive(Eq, PartialEq, Hash, Copy, Clone)] +struct Coordinate { + x: usize, + y: usize, +} + +fn main() { + let file_path = "input/10input.txt"; + let contents = fs::read_to_string(file_path).expect("should read file"); + let mut lines = contents.lines(); + let mut matrix: Vec> = Vec::new(); + loop { + match lines.next() { + Some(line) => { + matrix.push(line.chars().collect()); + }, + None => break, + } + } + let mut connection_map: HashMap> = HashMap::new(); + let mut starting_point: Coordinate = Coordinate { x: 0, y: 0}; + for i in 0..matrix.len() { + for j in 0..matrix[i].len() { + match matrix[i][j] { + '|' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j, y: i+1}]); + } + }, + '-' => { + if j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == 'J' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j-1, y: i}, Coordinate { x: j+1, y: i}]); + } + }, + 'L' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'J' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j+1, y: i}]); + } + } + 'J' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S' ) { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j-1, y: i}]); + } + } + '7' => { + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') && j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S' ) { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i+1}, Coordinate { x: j-1, y: i}]); + } + } + 'F' => { + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'J' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i+1}, Coordinate { x: j+1, y: i}]); + } + } + 'S' => { + starting_point = Coordinate{x: j, y: i}; + let mut to_insert: Vec = Vec::new(); + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F') { + to_insert.push(Coordinate { x: j, y: i-1}) + } + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J') { + to_insert.push(Coordinate { x: j, y: i+1}) + } + if j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F'){ + to_insert.push(Coordinate { x: j-1, y: i}) + } + if j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == 'J' || matrix[i][j+1] == '7') { + to_insert.push(Coordinate { x: j+1, y: i}) + } + connection_map.insert(Coordinate { x: j, y: i}, to_insert); + }, + _ => continue, + } + } + } + for i in 0..connection_map[&starting_point].len()-1 { + let mut current_coordinate = connection_map[&starting_point][i]; + let mut prev_coordinate = starting_point; + let mut count = 1; + while current_coordinate != starting_point && connection_map.get(¤t_coordinate).is_some() { + count += 1; + for j in 0..connection_map[¤t_coordinate].len() { + if connection_map[¤t_coordinate][j] != prev_coordinate { + prev_coordinate = current_coordinate; + current_coordinate = connection_map[¤t_coordinate][j]; + break; + } + } + } + if current_coordinate == starting_point { + println!("{}", count/2); + break; + } + } +} diff --git a/src/10part2.rs b/src/10part2.rs new file mode 100644 index 0000000..703eb82 --- /dev/null +++ b/src/10part2.rs @@ -0,0 +1,268 @@ +use std::{fs, collections::HashMap}; + +#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)] +struct Coordinate { + x: usize, + y: usize, +} + +#[derive(Eq, PartialEq)] +enum InLoop { + Loop = 1, + Outside = 2, +} + +fn main() { + let file_path = "input/10input.txt"; + let contents = fs::read_to_string(file_path).expect("should read file"); + let mut lines = contents.lines(); + let mut matrix: Vec> = Vec::new(); + loop { + match lines.next() { + Some(line) => { + matrix.push(line.chars().collect()); + }, + None => break, + } + } + let mut connection_map: HashMap> = HashMap::new(); + let mut starting_point: Coordinate = Coordinate { x: 0, y: 0}; + for i in 0..matrix.len() { + for j in 0..matrix[i].len() { + match matrix[i][j] { + '|' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j, y: i+1}]); + } + }, + '-' => { + if j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == 'J' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j-1, y: i}, Coordinate { x: j+1, y: i}]); + } + }, + 'L' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'J' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j+1, y: i}]); + } + } + 'J' => { + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F' || matrix[i-1][j] == 'S') && j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S' ) { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i-1}, Coordinate { x: j-1, y: i}]); + } + } + '7' => { + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') && j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F' || matrix[i][j-1] == 'S' ) { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i+1}, Coordinate { x: j-1, y: i}]); + } + } + 'F' => { + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J' || matrix[i+1][j] == 'S') && j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == '7' || matrix[i][j+1] == 'J' || matrix[i][j+1] == 'S') { + connection_map.insert(Coordinate { x: j, y: i}, vec![Coordinate { x: j, y: i+1}, Coordinate { x: j+1, y: i}]); + } + } + 'S' => { + starting_point = Coordinate{x: j, y: i}; + let mut to_insert: Vec = Vec::new(); + if i > 0 && (matrix[i-1][j] == '|' || matrix[i-1][j] == '7' || matrix[i-1][j] == 'F') { + to_insert.push(Coordinate { x: j, y: i-1}) + } + if i < matrix.len()-1 && (matrix[i+1][j] == '|' || matrix[i+1][j] == 'L' || matrix[i+1][j] == 'J') { + to_insert.push(Coordinate { x: j, y: i+1}) + } + if j > 0 && (matrix[i][j-1] == '-' || matrix[i][j-1] == 'L' || matrix[i][j-1] == 'F'){ + to_insert.push(Coordinate { x: j-1, y: i}) + } + if j < matrix[i].len()-1 && (matrix[i][j+1] == '-' || matrix[i][j+1] == 'J' || matrix[i][j+1] == '7') { + to_insert.push(Coordinate { x: j+1, y: i}) + } + connection_map.insert(Coordinate { x: j, y: i}, to_insert); + }, + _ => continue, + } + } + } + let mut loop_path: Vec = Vec::new(); + for i in 0..connection_map[&starting_point].len()-1 { + let mut potential_loop = vec![starting_point, connection_map[&starting_point][i]]; + while *potential_loop.last().unwrap() != starting_point && connection_map.get(&potential_loop.last().unwrap()).is_some() { + for j in 0..connection_map[potential_loop.last().unwrap()].len() { + if connection_map[potential_loop.last().unwrap()][j] != potential_loop[potential_loop.len()-2] { + potential_loop.push(connection_map[potential_loop.last().unwrap()][j]); + break; + } + } + } + if *potential_loop.last().unwrap() == starting_point { + loop_path = potential_loop; + break; + } + } + let mut inside_loop: HashMap = HashMap::new(); + for i in loop_path { + inside_loop.insert(i, InLoop::Loop); + } + for i in 0..matrix.len()/2+1 { + for j in 0..matrix[i].len()/2+1 { + if (!inside_loop.contains_key(&Coordinate{x:j, y:i}) || inside_loop[&Coordinate { x: j, y: i}] != InLoop::Loop) && ((i > 0 && inside_loop.contains_key(&Coordinate{x:j, y:i-1}) && inside_loop[&Coordinate{x:j, y:i-1}] == InLoop::Outside) || (j > 0 && inside_loop.contains_key(&Coordinate{x:j-1, y:i}) && inside_loop[&Coordinate{x:j-1, y:i}] == InLoop::Outside) || (i == 0 || j == 0)) { + inside_loop.insert(Coordinate{x:j, y:i}, InLoop::Outside); + } + if (!inside_loop.contains_key(&Coordinate { x: j, y: matrix.len()-i-1}) || inside_loop[&Coordinate {x:j, y:matrix.len()-i-1}] != InLoop::Loop) && ((i > 0 && inside_loop.contains_key(&Coordinate{x:j, y:matrix.len()-i}) && inside_loop[&Coordinate{x:j, y:matrix.len()-i}] == InLoop::Outside) || (j > 0 && inside_loop.contains_key(&Coordinate{x:j-1, y:matrix.len()-i-1}) && inside_loop[&Coordinate{x:j-1, y:matrix.len()-i-1}] == InLoop::Outside) || (i == 0 || j == 0)) { + inside_loop.insert(Coordinate{x:j, y:matrix.len()-i-1}, InLoop::Outside); + } + if (!inside_loop.contains_key(&Coordinate { x: matrix[i].len()-j-1, y: i}) || inside_loop[&Coordinate {x:matrix[i].len()-j-1, y:i}] != InLoop::Loop) && ((i > 0 && inside_loop.contains_key(&Coordinate{x:matrix[i].len()-j-1, y:i-1}) && inside_loop[&Coordinate{x:matrix[i].len()-j-1, y:i-1}] == InLoop::Outside) || (j > 0 && inside_loop.contains_key(&Coordinate{x:matrix[i].len()-j, y:i}) && inside_loop[&Coordinate{x:matrix[i].len()-j, y:i}] == InLoop::Outside) || (i == 0 || j == 0)) { + inside_loop.insert(Coordinate{x:matrix[i].len()-j-1, y:i}, InLoop::Outside); + } + if (!inside_loop.contains_key(&Coordinate { x: matrix[i].len()-j-1, y: matrix.len()-i-1}) || inside_loop[&Coordinate {x:matrix[i].len()-j-1, y:matrix.len()-i-1}] != InLoop::Loop) && ((i > 0 && inside_loop.contains_key(&Coordinate{x:matrix[i].len()-j-1, y:matrix.len()-i}) && inside_loop[&Coordinate{x:matrix[i].len()-j-1, y:matrix.len()-i}] == InLoop::Outside) || (j > 0 && inside_loop.contains_key(&Coordinate{x:matrix[i].len()-j, y:matrix.len()-i-1}) && inside_loop[&Coordinate{x:matrix[i].len()-j, y:matrix.len()-i-1}] == InLoop::Outside) || (i == 0 || j == 0)) { + inside_loop.insert(Coordinate{x:matrix[i].len()-j-1, y:matrix.len()-i-1}, InLoop::Outside); + } + } + } + for i in 0..matrix.len() { + for j in 0..matrix[i].len() { + if inside_loop.contains_key(&Coordinate { x: j, y: i}) { + match inside_loop[&Coordinate{x:j, y:i}] { + InLoop::Outside => print!("O"), + InLoop::Loop => print!("{}", matrix[i][j]), + } + } else { + print!("?") + } + } + println!(""); + } + let mut matrix_expanded: Vec> = Vec::new(); + let mut unknown_list = Vec::new(); + for i in 0..matrix.len() { + let mut row_a = Vec::new(); + let mut row_b = Vec::new(); + for j in 0..matrix[0].len() { + if inside_loop.contains_key(&Coordinate{x: j, y: i}) { + if inside_loop[&Coordinate{x: j, y: i}] == InLoop::Outside { + row_a.push('O'); + row_a.push('O'); + row_b.push('O'); + row_b.push('O'); + } else if inside_loop[&Coordinate{x:j, y:i}] == InLoop::Loop { + match matrix[i][j] { + '|' => { + row_a.push('|'); + row_b.push('|'); + if (i > 0 && matrix_expanded[i*2-1][j*2+1] == 'O') || i == 0 { + row_a.push('O'); + row_b.push('O'); + } else { + row_a.push('.'); + row_b.push('.'); + } + }, + '-' => { + row_a.push('-'); + row_a.push('-'); + if (j > 0 && row_b[row_b.len()-1] == 'O') || j == 0 { + row_b.push('O'); + row_b.push('O'); + } + else { + row_b.push('.'); + row_b.push('.'); + } + } + 'L' => { + row_a.push('L'); + row_a.push('-'); + if (j > 0 && row_b[row_b.len()-1] == 'O') || j == 0 { + row_b.push('O'); + row_b.push('O'); + } + else { + row_b.push('.'); + row_b.push('.'); + } + }, + 'J' => { + row_a.push('J'); + if (j > 0 && row_b[row_b.len()-1] == 'O') || j == 0 || (i > 0 && matrix_expanded[i*2-1][j*2+1] == 'O') || i == 0 { + row_a.push('O'); + row_b.push('O'); + row_b.push('O'); + } + else { + row_a.push('.'); + row_b.push('.'); + row_b.push('.'); + } + }, + '7' => { + row_a.push('7'); + row_b.push('|'); + if (i > 0 && matrix_expanded[i*2-1][j*2+1] == 'O') || i == 0 { + row_a.push('O'); + row_b.push('O'); + } else { + row_a.push('.'); + row_b.push('.'); + } + }, + 'F' => { + row_a.push('F'); + row_a.push('-'); + row_b.push('|'); + row_b.push('.'); + }, + 'S' => { + row_a.push('S'); + row_a.push('-'); + row_b.push('|'); + row_b.push('.'); + } + _ => {}, + } + } + } else { + row_a.push('.'); + row_a.push('.'); + row_b.push('.'); + row_b.push('.'); + } + } + println!("{:?}\n{:?}", row_a, row_b); + matrix_expanded.push(row_a); + matrix_expanded.push(row_b); + } + let mut y = matrix_expanded.len() -2; + while y > 0 { + let mut x = matrix_expanded[y].len() - 2; + while x > 0 { + if matrix_expanded[y][x] != '.' { + x -= 1; + continue; + } else if matrix_expanded[y][x-1] == 'O' || matrix_expanded[y-1][x] == 'O' || matrix_expanded[y][x+1] == 'O' || matrix_expanded[y+1][x] == 'O' { + matrix_expanded[y][x] = 'O'; + x -= 1; + } else { + unknown_list.push(Coordinate{x, y}); + x -= 1; + } + } + y -= 1; + } + let mut iters_since_last_update = 0; + while unknown_list.len() > iters_since_last_update { + let current = unknown_list.pop().unwrap(); + if matrix_expanded[current.y][current.x-1] == 'O' || matrix_expanded[current.y-1][current.x] == 'O' || matrix_expanded[current.y][current.x+1] == 'O' || matrix_expanded[current.y+1][current.x] == 'O' { + matrix_expanded[current.y][current.x] = 'O'; + iters_since_last_update = 0; + } else { + iters_since_last_update += 1; + unknown_list.insert(0, current); + } + } + let mut count = 0; + while unknown_list.len() > 0 { + let current = unknown_list.pop().unwrap(); + if current.x % 2 == 0 && current.y % 2 == 0 { + count+=1; + } + } + println!("{}", count); +}