diff --git a/assets/day_12_garden_input b/assets/day_12_garden_input new file mode 100644 index 0000000..85b768f --- /dev/null +++ b/assets/day_12_garden_input @@ -0,0 +1,10 @@ +RRRRIICCFF +RRRRIICCCF +VVRRRCCFFF +VVRCCCJFFF +VVVVCJJCFE +VVIVCCJJEE +VVIIICJJEE +MIIIIIJJEE +MIIISIJEEE +MMMISSJEEE diff --git a/src/advent_of_code/mod.rs b/src/advent_of_code/mod.rs index c1c4731..f1ab46a 100644 --- a/src/advent_of_code/mod.rs +++ b/src/advent_of_code/mod.rs @@ -98,4 +98,8 @@ pub fn historian_hysteria() { // "The total of stones after {} is {}", // blink_count, stone_count // ); + + // Thursday 12 + let fence_cost = thu_12::garden_groups("./assets/day_12_garden_input"); + println!("The garden fence total cost is {}", fence_cost); } diff --git a/src/advent_of_code/thu_12.rs b/src/advent_of_code/thu_12.rs index b7b1be3..139e733 100644 --- a/src/advent_of_code/thu_12.rs +++ b/src/advent_of_code/thu_12.rs @@ -1,16 +1,114 @@ use super::*; -pub fn garden_groups(input: &str) { +pub fn garden_groups(input: &str) -> usize { let garden = utils::read_garden_arrangement_input(input); + + let plot_list = get_plot_list(&garden); + + let mut total_cost: usize = 0; + + for plot in plot_list { + println!("Plot: {:?}", plot); + total_cost += plot.side_count * plot.plant_list.len(); + } + + total_cost } -pub fn get_plot_list(map: &Garden) -> Plot { - let plot = Plot{} +pub fn get_plot_list(map: &Garden) -> PlotList { + let mut plot_list: PlotList = vec![]; + + for (row_index, row) in map.iter().enumerate() { + for (plant_index, plant) in row.iter().enumerate() { + let new_coord = Coordinate { + x: plant_index, + y: row_index, + }; + // FIXME: this does not cover all the cases! Any linear plot wont be covered + if row_index > 0 { + if let Some(plot_index) = which_plot_contains_coords( + &plot_list, + Coordinate { + x: plant_index, + y: row_index - 1, + }, + ) { + if plot_list[plot_index].plant == *plant { + plot_list[plot_index].plant_list.push(new_coord); + plot_list[plot_index].side_count += calc_sides_of_plant( + map, + &Coordinate { + x: plant_index, + y: row_index, + }, + plant, + ); + continue; + } + } + } + if plant_index > 0 { + if let Some(plot_index) = which_plot_contains_coords( + &plot_list, + Coordinate { + x: plant_index - 1, + y: row_index, + }, + ) { + if plot_list[plot_index].plant == *plant { + plot_list[plot_index].plant_list.push(new_coord); + plot_list[plot_index].side_count += calc_sides_of_plant( + map, + &Coordinate { + x: plant_index, + y: row_index, + }, + plant, + ); + + continue; + } + } + } + + plot_list.push(Plot { + plant: *plant, + side_count: calc_sides_of_plant(map, &new_coord, plant), + plant_list: vec![new_coord], + }); + } + } + + plot_list } -pub fn which_plot_contains_coords(list: &PlotList, coord: Coorinate) -> Option { +pub fn calc_sides_of_plant(map: &Garden, coord: &Coordinate, plant: &Plant) -> usize { + let mut sum: usize = 0; + + if coord.x == 0 || map[coord.y][coord.x - 1] != *plant { + sum += 1; + } + + if coord.y == 0 || map[coord.y - 1][coord.x] != *plant { + sum += 1; + } + + if coord.x < map[0].len() - 2 && map[coord.y][coord.x + 1] != *plant + || coord.x == map[0].len() - 1 + { + sum += 1; + } + + if coord.y < map.len() - 2 && map[coord.y + 1][coord.x] != *plant || coord.y == map.len() - 1 { + sum += 1; + } + + sum +} + +pub fn which_plot_contains_coords(list: &PlotList, coord: Coordinate) -> Option { for (plot_index, plot) in list.iter().enumerate() { - if plot.plant_list.contains(coord) { + if plot.plant_list.contains(&coord) { return Some(plot_index); } } diff --git a/src/advent_of_code/types.rs b/src/advent_of_code/types.rs index 86f1a04..090bdd3 100644 --- a/src/advent_of_code/types.rs +++ b/src/advent_of_code/types.rs @@ -91,11 +91,13 @@ pub type StoneList = Vec; pub type Plant = char; pub type Garden = Vec>; -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] pub struct Coordinate { pub x: usize, pub y: usize, } + +#[derive(Debug)] pub struct Plot { pub plant: Plant, pub side_count: usize, diff --git a/src/advent_of_code/utils.rs b/src/advent_of_code/utils.rs index ab51c59..39bc792 100644 --- a/src/advent_of_code/utils.rs +++ b/src/advent_of_code/utils.rs @@ -1,5 +1,4 @@ use std::fs::read_to_string; -use std::io::read_to_string; use std::ops::Sub; use super::*;