Compare commits

..

10 Commits

13 changed files with 507 additions and 25 deletions

View File

@@ -11,9 +11,9 @@ https://adventofcode.com/2024
| 06 | Guard Gallivant | :pushpin: | :pushpin: | 2D navigation |
| 07 | Bridge Repair | :pushpin: | :pushpin: | Equation parsing |
| 08 | Resonant Collinearity | :pushpin: | | Matrix exploration |
| 09 | Disk fragmenter | | | |
| 10 | | | | |
| 11 | | | | |
| 09 | Disk fragmenter | :pushpin: | | Array indexing |
| 10 | Hoof It | :pushpin: | :pushpin: | Path finding |
| 11 | Plutonian Pebbles | :pushpin: | | Array and digit manipulation |
| 12 | | | | |
| 13 | | | | |
| 14 | | | | |

View File

@@ -0,0 +1,44 @@
12109832101432101234107652158943210178765892
03078456210145696701218943067654396549456701
54562364345436789874327832107810387630345210
65401875696925210765498017656901234521254321
78078956787814321544567328943217890012189450
69101045698701055432123410812206921983098765
43232132509652566785010569701105435674549056
58943001419143478994321678983210304105678143
67653214328012988765690787894321213289437212
45654301037001089650787096765010034576524301
56789890156121072341256101896654123678915498
43276765243234561212345234987783210569206789
54109854312789870109012345676898765454106543
45610123203650105438721056765609674323287012
54781010154543216521635489832014589210398013
67898543269854107610544376541023008101296323
54987656576765678923455210458782112010387456
23122189983454989012966904349698103465456567
12033078012763210101877813234521098578956798
03944565430887654012109320121034787632347897
87856556021991047121238458945695698961036016
96587432110872338930347567232780087654105125
01498983321265427945656089101091109803234934
32327465456766016859890176232892256712107843
21012334569854105766763245001743343893256765
30503129678945234897854632122654872894349854
45614068798234012656906543213458961783210703
21765878907178723765417891008965450654125612
30854965416069654894328982567872342103054503
48903010325450560761237813450561003276543678
56012321210341981230106504341540214789432189
67329630121212870341012415432634345695321012
78478742198903965494543326998723456786540765
89569653087654654987696547889010567847830874
21052104676501723898587032378765676956921923
32343015685432810767698121459034982349650010
10478723794354903456567030760121061078744567
21569654891263212347450177898267877101233498
32108765430678903038321789783454978715012399
47899834320545676129012876012543269856101087
56938723011230983543903965987650156747801256
40127619654321012652874854107890349832954343
30034508763018723761765543236501212721096501
21065619012349654890101234565432301430787432

View File

@@ -0,0 +1 @@
2 77706 5847 9258441 0 741 883933 12

View File

@@ -0,0 +1,10 @@
RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE

View File

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,10 @@
// mod fri_06;
// mod sat_07;
// mod sun_08;
mod mon_09;
// mod mon_09;
// mod tue_10;
// mod wed_11;
mod thu_12;
mod types;
mod utils;
@@ -73,5 +76,30 @@ pub fn historian_hysteria() {
// );
// Monday 09
let disk_checksum = mon_09::disk_fragmenter("./assets/day_9_disk_input");
// let disk_checksum = mon_09::disk_fragmenter("./assets/day_9_disk_input");
// println!("The disk checksum is {}", disk_checksum);
// Tuesday 10
// let (trailhead_score, full_trailhead_score) =
// tue_10::hoof_it("./assets/day_10_trail_map_input");
// println!("The trail head sum score is {}", trailhead_score);
// println!("The full trail head sum score is {}", full_trailhead_score);
// let blink_count: usize = 25;
// let stone_count =
// wed_11::plutonian_pebbles("./assets/day_11_stone_arrangement_input", blink_count);
// println!(
// "The total of stones after {} is {}",
// blink_count, stone_count
// );
// let blink_count: usize = 75;
// let stone_count =
// wed_11::plutonian_pebbles("./assets/day_11_stone_arrangement_input", blink_count);
// println!(
// "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);
}

View File

@@ -1,19 +1,51 @@
use super::{utils::read_disk_map_input, DiskMap};
use super::{utils::read_disk_map_input, DiskChecksum, DiskMap};
pub fn disk_fragmenter(input: &str) -> usize {
pub fn disk_fragmenter(input: &str) -> DiskChecksum {
let disk_map = read_disk_map_input(input);
let organized_disk_map = organize_disk_map(&disk_map);
println!("{:?}", disk_map);
println!("{:?}", organized_disk_map);
let organized_disk_map = organize_disk_map(disk_map);
0
calc_disk_check_sum(&organized_disk_map)
}
pub fn organize_disk_map(disk_map: &DiskMap) -> DiskMap {
let organized_disk_map: DiskMap = vec![];
pub fn organize_disk_map(mut disk_map: DiskMap) -> DiskMap {
let mut end_index: usize = disk_map.len() - 1;
let mut start_index: usize = 0;
for block in disk_map {}
'outer: loop {
if end_index <= start_index || start_index > disk_map.len() - 1 {
break 'outer;
}
organized_disk_map
if let None = disk_map[start_index] {
'inner: loop {
if end_index <= start_index {
break 'inner;
}
if let Some(_) = disk_map[end_index] {
disk_map.swap(start_index, end_index);
break 'inner;
}
end_index -= 1;
}
}
start_index += 1;
}
disk_map
}
pub fn calc_disk_check_sum(disk_map: &DiskMap) -> DiskChecksum {
let mut checksum: DiskChecksum = 0;
for (block_index, block) in disk_map.iter().enumerate() {
if let Some(id) = block {
checksum += *id as DiskChecksum * block_index as DiskChecksum;
} else {
break;
}
}
checksum as DiskChecksum
}

View File

@@ -0,0 +1,121 @@
use super::*;
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) -> 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 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<usize> {
for (plot_index, plot) in list.iter().enumerate() {
if plot.plant_list.contains(&coord) {
return Some(plot_index);
}
}
None
}
// Perimeter is calculated looping over the elements and adding every non-member.
//
// mutate the garden on every iteration to avoid exploring already counted areas

View File

@@ -0,0 +1,119 @@
use utils::read_trail_map_input;
use super::*;
pub fn hoof_it(input: &str) -> (usize, usize) {
let trail_map = read_trail_map_input(input);
let (vector_of_scores, vector_of_all_scores) = explore_map(trail_map);
let mut sum_of_scores: usize = 0;
// TODO: improve, this is dirty
for score in vector_of_scores {
sum_of_scores += score;
}
let mut sum_of_all_scores: usize = 0;
for score in vector_of_all_scores {
sum_of_all_scores += score;
}
(sum_of_scores, sum_of_all_scores)
}
pub fn explore_map(map: TrailMap) -> (Vec<TrailScore>, Vec<TrailScore>) {
let mut trail_score_list: Vec<TrailScore> = vec![];
let mut full_trail_score_list: Vec<TrailScore> = vec![];
for y_index in 0..map.len() {
for x_index in 0..map[y_index].len() {
if map[y_index][x_index] == 0 {
let mut reached_ends: Vec<(usize, usize)> = vec![];
trail_score_list.push(explore_position(x_index, y_index, &map, &mut reached_ends));
full_trail_score_list.push(explore_all_positions(x_index, y_index, &map));
}
}
}
(trail_score_list, full_trail_score_list)
}
pub fn explore_position(
x: TrailPosition,
y: TrailPosition,
map: &TrailMap,
reached_ends: &mut Vec<(usize, usize)>,
) -> usize {
if map[y][x] == 9 {
reached_ends.push((x, y));
return 1;
}
let mut score_sum: usize = 0;
for next_position in get_pos_surroundings(x, y, map) {
if map[next_position.1][next_position.0] == map[y][x] + 1
&& !reached_ends.contains(&(next_position.0, next_position.1))
{
score_sum += explore_position(next_position.0, next_position.1, map, reached_ends);
}
}
score_sum
}
pub fn explore_all_positions(x: TrailPosition, y: TrailPosition, map: &TrailMap) -> usize {
if map[y][x] == 9 {
return 1;
}
let mut score_sum: usize = 0;
for next_position in get_pos_surroundings(x, y, map) {
if map[next_position.1][next_position.0] == map[y][x] + 1 {
score_sum += explore_all_positions(next_position.0, next_position.1, map);
}
}
score_sum
}
pub fn get_pos_surroundings(
x: TrailPosition,
y: TrailPosition,
map: &TrailMap,
) -> Vec<(usize, usize)> {
let mut trail_pos_vec: Vec<(usize, usize)> = vec![];
if x > 0 {
trail_pos_vec.push((x - 1, y));
// if y > 0 {
// trail_pos_vec.push((x - 1, y - 1));
// }
// if y < map.len() - 1 {
// trail_pos_vec.push((x - 1, y + 1));
// }
}
if x < map[0].len() - 1 {
trail_pos_vec.push((x + 1, y));
// if y > 0 {
// trail_pos_vec.push((x + 1, y - 1));
// }
//
// if y < map.len() - 1 {
// trail_pos_vec.push((x + 1, y + 1));
// }
}
if y > 0 {
trail_pos_vec.push((x, y - 1));
}
if y < map.len() - 1 {
trail_pos_vec.push((x, y + 1));
}
trail_pos_vec
}

View File

@@ -75,3 +75,33 @@ pub type AntinodeList = HashSet<Antinode>;
// Disk fragmenter
pub type Block = Option<usize>;
pub type DiskMap = Vec<Block>;
pub type DiskChecksum = usize;
// Hoof it
pub type TrailScore = usize;
pub type TrailPosition = usize;
pub type TrailMap = Vec<Vec<TrailPosition>>;
// Plutonian Pebbles
pub type StoneCount = usize;
pub type Stone = usize;
pub type StoneList = Vec<Stone>;
// Garden Groups
pub type Plant = char;
pub type Garden = Vec<Vec<char>>;
#[derive(PartialEq, Debug)]
pub struct Coordinate {
pub x: usize,
pub y: usize,
}
#[derive(Debug)]
pub struct Plot {
pub plant: Plant,
pub side_count: usize,
pub plant_list: Vec<Coordinate>,
}
pub type PlotList = Vec<Plot>;

View File

@@ -170,16 +170,18 @@ pub fn read_disk_map_input(input: &str) -> DiskMap {
let mut id: usize = 0;
for (digit_index, char_digit) in raw_map.chars().enumerate() {
if let Some(digit) = char_digit.to_digit(10u32) {
for _ in 0..digit {
if digit_index % 2 == 0 {
disk_map.push(Some(id));
} else {
disk_map.push(None);
if let Some(digit) = char_digit.to_digit(10) {
if digit > 0 {
for _ in 0..digit {
if digit_index % 2 == 0 {
disk_map.push(Some(id));
} else {
disk_map.push(None);
}
}
if digit_index % 2 == 0 {
id += 1;
}
}
if digit_index % 2 == 0 {
id += 1;
}
}
}
@@ -187,6 +189,49 @@ pub fn read_disk_map_input(input: &str) -> DiskMap {
disk_map
}
pub fn read_trail_map_input(input: &str) -> TrailMap {
let mut trail_map: TrailMap = vec![];
for line in read_to_string(input).unwrap().lines() {
let mut trail_row: Vec<usize> = vec![];
for position in line.chars() {
if let Some(digit) = position.to_digit(10) {
trail_row.push(digit as usize);
}
}
trail_map.push(trail_row);
}
trail_map
}
pub fn read_stone_arrangement(input: &str) -> StoneList {
let mut stone_list: StoneList = vec![];
for line in read_to_string(input).unwrap().lines() {
for number in line.split(" ") {
stone_list.push(number.parse::<Stone>().unwrap());
}
}
stone_list
}
pub fn read_garden_arrangement_input(input: &str) -> Garden {
let mut garden: Garden = vec![];
for line in read_to_string(input).unwrap().lines() {
let mut garden_row: Vec<Plant> = vec![];
for plant in line.chars() {
garden_row.push(plant);
}
garden.push(garden_row);
}
garden
}
pub fn calc_distance<T>(num_1: T, num_2: T) -> T
where
T: PartialOrd + Sub<Output = T>,

View File

@@ -0,0 +1,51 @@
use super::*;
pub fn plutonian_pebbles(input: &str, blink_count: usize) -> StoneCount {
let stone_list = utils::read_stone_arrangement(input);
let stone_list = apply_rules(stone_list, blink_count);
stone_list.len()
}
fn apply_rules(mut stone_list: StoneList, blink_count: usize) -> StoneList {
for _ in 0..blink_count {
stone_list = blink(stone_list);
}
stone_list
}
fn blink(stone_list: StoneList) -> StoneList {
let mut new_stone_list: StoneList = vec![];
const STONE_MULTIPLIER: usize = 2024;
for stone in stone_list {
match stone {
0 => {
new_stone_list.push(1);
}
stone if stone.to_string().len() % 2 == 0 => {
let (left, right) = split_num(stone);
new_stone_list.push(left);
new_stone_list.push(right);
}
_ => {
new_stone_list.push(stone * STONE_MULTIPLIER);
}
}
}
new_stone_list
}
fn split_num(num: Stone) -> (Stone, Stone) {
let split_index = num.to_string().len() / 2;
let binding = num.to_string();
let (first, second) = binding.split_at(split_index);
(
first.parse::<Stone>().unwrap(),
second.parse::<Stone>().unwrap(),
)
}

View File

@@ -1,3 +1,4 @@
#![allow(dead_code)]
mod advent_of_code;
fn main() {