Day 10 complete

This commit is contained in:
Cassandra de la Cruz-Munoz 2023-12-11 13:34:53 +01:00
parent 1f225db08d
commit f09ab515bb
2 changed files with 365 additions and 0 deletions

97
src/10part1.rs Normal file
View File

@ -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<char>> = Vec::new();
loop {
match lines.next() {
Some(line) => {
matrix.push(line.chars().collect());
},
None => break,
}
}
let mut connection_map: HashMap<Coordinate, Vec<Coordinate>> = 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<Coordinate> = 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(&current_coordinate).is_some() {
count += 1;
for j in 0..connection_map[&current_coordinate].len() {
if connection_map[&current_coordinate][j] != prev_coordinate {
prev_coordinate = current_coordinate;
current_coordinate = connection_map[&current_coordinate][j];
break;
}
}
}
if current_coordinate == starting_point {
println!("{}", count/2);
break;
}
}
}

268
src/10part2.rs Normal file
View File

@ -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<char>> = Vec::new();
loop {
match lines.next() {
Some(line) => {
matrix.push(line.chars().collect());
},
None => break,
}
}
let mut connection_map: HashMap<Coordinate, Vec<Coordinate>> = 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<Coordinate> = 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<Coordinate> = 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<Coordinate, InLoop> = 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<char>> = 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);
}