Compare commits
11 Commits
62a9aec76d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 523142f2f6 | |||
| bb04979b45 | |||
| 4b3d1ee85a | |||
| 8a49944e00 | |||
| 49ed857a18 | |||
| d5dae5dee7 | |||
| 39d61cb91d | |||
| e896429b99 | |||
| d25a2cfa99 | |||
| 2312f2a549 | |||
| 7f36519fcc |
@@ -11,9 +11,9 @@ https://adventofcode.com/2024
|
|||||||
| 06 | Guard Gallivant | :pushpin: | :pushpin: | 2D navigation |
|
| 06 | Guard Gallivant | :pushpin: | :pushpin: | 2D navigation |
|
||||||
| 07 | Bridge Repair | :pushpin: | :pushpin: | Equation parsing |
|
| 07 | Bridge Repair | :pushpin: | :pushpin: | Equation parsing |
|
||||||
| 08 | Resonant Collinearity | :pushpin: | | Matrix exploration |
|
| 08 | Resonant Collinearity | :pushpin: | | Matrix exploration |
|
||||||
| 09 | Disk fragmenter | | | |
|
| 09 | Disk fragmenter | :pushpin: | | Array indexing |
|
||||||
| 10 | | | | |
|
| 10 | Hoof It | :pushpin: | :pushpin: | Path finding |
|
||||||
| 11 | | | | |
|
| 11 | Plutonian Pebbles | :pushpin: | | Array and digit manipulation |
|
||||||
| 12 | | | | |
|
| 12 | | | | |
|
||||||
| 13 | | | | |
|
| 13 | | | | |
|
||||||
| 14 | | | | |
|
| 14 | | | | |
|
||||||
|
|||||||
44
assets/day_10_trail_map_input
Normal file
44
assets/day_10_trail_map_input
Normal 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
|
||||||
1
assets/day_11_stone_arrangement_input
Normal file
1
assets/day_11_stone_arrangement_input
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2 77706 5847 9258441 0 741 883933 12
|
||||||
10
assets/day_12_garden_input
Normal file
10
assets/day_12_garden_input
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
RRRRIICCFF
|
||||||
|
RRRRIICCCF
|
||||||
|
VVRRRCCFFF
|
||||||
|
VVRCCCJFFF
|
||||||
|
VVVVCJJCFE
|
||||||
|
VVIVCCJJEE
|
||||||
|
VVIIICJJEE
|
||||||
|
MIIIIIJJEE
|
||||||
|
MIIISIJEEE
|
||||||
|
MMMISSJEEE
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,12 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let key = get_key("./assets/day_1_input").unwrap();
|
||||||
|
println!("The key is: {key}");
|
||||||
|
let similarity = get_similarity("./assets/day_1_input");
|
||||||
|
println!("The similarity is: {similarity}");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_key(input: &str) -> Result<Key, ()> {
|
pub fn get_key(input: &str) -> Result<Key, ()> {
|
||||||
let mut key: Id = 0;
|
let mut key: Id = 0;
|
||||||
|
|
||||||
@@ -2,6 +2,11 @@ use utils::{calc_distance, read_report_list};
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let safe_report_count = check_reports_safety("./assets/day_2_reports_input");
|
||||||
|
println!("There are {safe_report_count} safe reports");
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_reports_safety(input: &str) -> ReportSafety {
|
pub fn check_reports_safety(input: &str) -> ReportSafety {
|
||||||
let report_list = read_report_list(input);
|
let report_list = read_report_list(input);
|
||||||
|
|
||||||
@@ -3,6 +3,20 @@ use utils::read_instruction_input;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let multiplication_added_result = mull_it_over("./assets/day_3_instruction_input");
|
||||||
|
println!(
|
||||||
|
"The result of the sum of multiplications is {}",
|
||||||
|
multiplication_added_result
|
||||||
|
);
|
||||||
|
let conditional_multiplication_added_result =
|
||||||
|
mull_it_over_conditional("./assets/day_3_instruction_input");
|
||||||
|
println!(
|
||||||
|
"The result of the conditional sum of multiplications is {}",
|
||||||
|
conditional_multiplication_added_result
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mull_it_over(input: &str) -> MulNumber {
|
pub fn mull_it_over(input: &str) -> MulNumber {
|
||||||
let instruction_input = read_instruction_input(input);
|
let instruction_input = read_instruction_input(input);
|
||||||
|
|
||||||
@@ -5,6 +5,12 @@ use super::*;
|
|||||||
const SEARCHED_WORD: &str = "XMAS";
|
const SEARCHED_WORD: &str = "XMAS";
|
||||||
const X_SEARCHED_WORD: &str = "MAS";
|
const X_SEARCHED_WORD: &str = "MAS";
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let (xmas_appearances, x_mas_appearances) = ceres_search("./assets/day_4_input");
|
||||||
|
println!("XMAS appears {} times", xmas_appearances);
|
||||||
|
println!("X-MAS appears {} times", x_mas_appearances);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ceres_search(input: &str) -> (XMASCount, XMASCount) {
|
pub fn ceres_search(input: &str) -> (XMASCount, XMASCount) {
|
||||||
let puzzle_matrix = read_ceres_puzzle_input(input);
|
let puzzle_matrix = read_ceres_puzzle_input(input);
|
||||||
|
|
||||||
@@ -2,6 +2,12 @@ use utils::read_rules_and_queue;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let (queue_mid_sum, fixed_queue_mid_sum) = mid_queue_sum("./assets/day_5_rules_queue_input");
|
||||||
|
println!("The update mid-queue-sum is {}", queue_mid_sum);
|
||||||
|
println!("The fixed update mid-queue-sum is {}", fixed_queue_mid_sum);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mid_queue_sum(input: &str) -> (u32, u32) {
|
pub fn mid_queue_sum(input: &str) -> (u32, u32) {
|
||||||
let (rules, queues) = read_rules_and_queue(input);
|
let (rules, queues) = read_rules_and_queue(input);
|
||||||
|
|
||||||
@@ -2,6 +2,13 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let (guard_position_count, loop_obstacle_count) =
|
||||||
|
guard_gallivant("./assets/day_6_guard_map_input");
|
||||||
|
println!("The guard will visit {} positions", guard_position_count);
|
||||||
|
println!("The guard would loop on {} positions", loop_obstacle_count);
|
||||||
|
}
|
||||||
|
|
||||||
impl Guard {
|
impl Guard {
|
||||||
fn step(&mut self, map: &FloorMap) -> IsGuardOut {
|
fn step(&mut self, map: &FloorMap) -> IsGuardOut {
|
||||||
let mut future_x = self.x;
|
let mut future_x = self.x;
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let calibration_result = bridge_repair("./assets/day_7_calibrations_input");
|
||||||
|
println!("The total calibration result is {}", calibration_result);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn bridge_repair(input: &str) -> CalibrationResult {
|
pub fn bridge_repair(input: &str) -> CalibrationResult {
|
||||||
let equation_vec = utils::read_calibration_equations(input);
|
let equation_vec = utils::read_calibration_equations(input);
|
||||||
let mut sum_result: CalibrationResult = 0;
|
let mut sum_result: CalibrationResult = 0;
|
||||||
@@ -4,41 +4,25 @@ use utils::read_antena_map_input;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let (antinode_count, antinode_count_any) =
|
||||||
|
resonant_collinearity("./assets/day_8_antena_map_input");
|
||||||
|
println!("The total antinode positions is {}", antinode_count);
|
||||||
|
println!(
|
||||||
|
"The total antinode positions in any grid is {}",
|
||||||
|
antinode_count_any
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resonant_collinearity(input: &str) -> (AntinodeCount, AntinodeCount) {
|
pub fn resonant_collinearity(input: &str) -> (AntinodeCount, AntinodeCount) {
|
||||||
let (roof_map, antena_list) = read_antena_map_input(input);
|
let (roof_map, antena_list) = read_antena_map_input(input);
|
||||||
|
|
||||||
(
|
(
|
||||||
get_antinode_set_of_aligned_position(&antena_list, &roof_map).len(),
|
get_antinode_set_of_aligned_position(&antena_list, &roof_map).len(),
|
||||||
get_antinode_set_of_any_aligned_position(&antena_list, &roof_map).len(),
|
0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_antinode_set_of_any_aligned_position(
|
|
||||||
antena_list: &AntenaList,
|
|
||||||
map: &RoofMap,
|
|
||||||
) -> AntinodeList {
|
|
||||||
let mut antinode_list: AntinodeList = HashSet::new();
|
|
||||||
|
|
||||||
for antena in antena_list {
|
|
||||||
for complementary_antena in antena_list {
|
|
||||||
if antena != complementary_antena && antena.2 == complementary_antena.2 {
|
|
||||||
let distance_x = (antena.1 as i32 - complementary_antena.1 as i32).abs() as usize;
|
|
||||||
let distance_y = (antena.0 as i32 - complementary_antena.0 as i32).abs() as usize;
|
|
||||||
|
|
||||||
let mut count: usize = 0;
|
|
||||||
|
|
||||||
// loop {
|
|
||||||
// let test_x = distance_x * count;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// antinode_list.insert(pair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
antinode_list
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_antinode_set_of_aligned_position(
|
pub fn get_antinode_set_of_aligned_position(
|
||||||
antena_list: &AntenaList,
|
antena_list: &AntenaList,
|
||||||
map: &RoofMap,
|
map: &RoofMap,
|
||||||
@@ -200,8 +184,8 @@ pub fn is_station_between(a: (usize, usize), b: (usize, usize), map: &RoofMap) -
|
|||||||
let x_diff = (a.1 as i32 - b.1 as i32).abs() as usize;
|
let x_diff = (a.1 as i32 - b.1 as i32).abs() as usize;
|
||||||
|
|
||||||
'check_diagonal: loop {
|
'check_diagonal: loop {
|
||||||
let mut next_x: i32 = 0;
|
let next_x: i32;
|
||||||
let mut next_y: i32 = 0;
|
let next_y: i32;
|
||||||
|
|
||||||
if a.1 > b.1 {
|
if a.1 > b.1 {
|
||||||
if a.0 > b.0 {
|
if a.0 > b.0 {
|
||||||
@@ -240,6 +224,7 @@ pub fn is_station_between(a: (usize, usize), b: (usize, usize), map: &RoofMap) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(_) = map[next_y as usize][next_x as usize] {
|
if let Some(_) = map[next_y as usize][next_x as usize] {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
56
src/advent_of_code/day_09.rs
Normal file
56
src/advent_of_code/day_09.rs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
use super::{utils::read_disk_map_input, DiskChecksum, DiskMap};
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let disk_checksum = disk_fragmenter("./assets/day_9_disk_input");
|
||||||
|
println!("The disk checksum is {}", disk_checksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disk_fragmenter(input: &str) -> DiskChecksum {
|
||||||
|
let disk_map = read_disk_map_input(input);
|
||||||
|
|
||||||
|
let organized_disk_map = organize_disk_map(disk_map);
|
||||||
|
|
||||||
|
calc_disk_check_sum(&organized_disk_map)
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
'outer: loop {
|
||||||
|
if end_index <= start_index || start_index > disk_map.len() - 1 {
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
125
src/advent_of_code/day_10.rs
Normal file
125
src/advent_of_code/day_10.rs
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
use utils::read_trail_map_input;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let (trailhead_score, full_trailhead_score) = 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
66
src/advent_of_code/day_11.rs
Normal file
66
src/advent_of_code/day_11.rs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let blink_count: usize = 25;
|
||||||
|
let stone_count = 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 = plutonian_pebbles("./assets/day_11_stone_arrangement_input", blink_count);
|
||||||
|
println!(
|
||||||
|
"The total of stones after {} is {}",
|
||||||
|
blink_count, stone_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
126
src/advent_of_code/day_12.rs
Normal file
126
src/advent_of_code/day_12.rs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn today() {
|
||||||
|
let fence_cost = garden_groups("./assets/day_12_garden_input");
|
||||||
|
println!("The garden fence total cost is {}", fence_cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
@@ -1,77 +1,60 @@
|
|||||||
// mod sun_01;
|
mod day_01;
|
||||||
// mod mon_02;
|
mod day_02;
|
||||||
// mod tue_03;
|
mod day_03;
|
||||||
// mod wed_04;
|
mod day_04;
|
||||||
// mod thu_05;
|
mod day_05;
|
||||||
// mod fri_06;
|
mod day_06;
|
||||||
// mod sat_07;
|
mod day_07;
|
||||||
// mod sun_08;
|
mod day_08;
|
||||||
mod mon_09;
|
mod day_09;
|
||||||
|
mod day_10;
|
||||||
|
mod day_11;
|
||||||
|
mod day_12;
|
||||||
mod types;
|
mod types;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
pub fn today() {
|
pub fn today(day: u8) {
|
||||||
historian_hysteria()
|
match day {
|
||||||
|
1 => {
|
||||||
|
day_01::today();
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
day_02::today();
|
||||||
|
}
|
||||||
|
3 => {
|
||||||
|
day_03::today();
|
||||||
|
}
|
||||||
|
4 => {
|
||||||
|
day_04::today();
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
day_05::today();
|
||||||
|
}
|
||||||
|
6 => {
|
||||||
|
day_06::today();
|
||||||
|
}
|
||||||
|
7 => {
|
||||||
|
day_07::today();
|
||||||
|
}
|
||||||
|
8 => {
|
||||||
|
day_08::today();
|
||||||
|
}
|
||||||
|
9 => {
|
||||||
|
day_09::today();
|
||||||
|
}
|
||||||
|
10 => {
|
||||||
|
day_10::today();
|
||||||
|
}
|
||||||
|
11 => {
|
||||||
|
day_11::today();
|
||||||
|
}
|
||||||
|
12 => {
|
||||||
|
day_12::today();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("Not a valid day.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn historian_hysteria() {
|
|
||||||
// NOTE: previous days are commented to speed up (all the blame is on day 6)
|
|
||||||
|
|
||||||
// Sunday 01
|
|
||||||
// let key = sun_01::get_key("./assets/day_1_input").unwrap();
|
|
||||||
// println!("The key is: {key}");
|
|
||||||
// let similarity = sun_01::get_similarity("./assets/day_1_input");
|
|
||||||
// println!("The similarity is: {similarity}");
|
|
||||||
|
|
||||||
// Monday 02
|
|
||||||
// let safe_report_count = mon_02::check_reports_safety("./assets/day_2_reports_input");
|
|
||||||
// println!("There are {safe_report_count} safe reports");
|
|
||||||
|
|
||||||
// Tuesday 03
|
|
||||||
// let multiplication_added_result = tue_03::mull_it_over("./assets/day_3_instruction_input");
|
|
||||||
// println!(
|
|
||||||
// "The result of the sum of multiplications is {}",
|
|
||||||
// multiplication_added_result
|
|
||||||
// );
|
|
||||||
// let conditional_multiplication_added_result =
|
|
||||||
// tue_03::mull_it_over_conditional("./assets/day_3_instruction_input");
|
|
||||||
// println!(
|
|
||||||
// "The result of the conditional sum of multiplications is {}",
|
|
||||||
// conditional_multiplication_added_result
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Wednesday 04
|
|
||||||
// let (xmas_appearances, x_mas_appearances) = wed_04::ceres_search("./assets/day_4_input");
|
|
||||||
// println!("XMAS appears {} times", xmas_appearances);
|
|
||||||
// println!("X-MAS appears {} times", x_mas_appearances);
|
|
||||||
|
|
||||||
// Thursday 05
|
|
||||||
// let (queue_mid_sum, fixed_queue_mid_sum) =
|
|
||||||
// thu_05::mid_queue_sum("./assets/day_5_rules_queue_input");
|
|
||||||
// println!("The update mid-queue-sum is {}", queue_mid_sum);
|
|
||||||
// println!("The fixed update mid-queue-sum is {}", fixed_queue_mid_sum);
|
|
||||||
|
|
||||||
// Friday 06
|
|
||||||
// let (guard_position_count, loop_obstacle_count) =
|
|
||||||
// fri_06::guard_gallivant("./assets/day_6_guard_map_input");
|
|
||||||
// println!("The guard will visit {} positions", guard_position_count);
|
|
||||||
// println!("The guard would loop on {} positions", loop_obstacle_count);
|
|
||||||
|
|
||||||
// Saturday 07
|
|
||||||
// let calibration_result = sat_07::bridge_repair("./assets/day_7_calibrations_input");
|
|
||||||
// println!("The total calibration result is {}", calibration_result);
|
|
||||||
|
|
||||||
// Sunday 08
|
|
||||||
// let (antinode_count, antinode_count_any) =
|
|
||||||
// sun_08::resonant_collinearity("./assets/day_8_antena_map_input");
|
|
||||||
// println!("The total antinode positions is {}", antinode_count);
|
|
||||||
// println!(
|
|
||||||
// "The total antinode positions in any grid is {}",
|
|
||||||
// antinode_count_any
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Monday 09
|
|
||||||
let disk_checksum = mon_09::disk_fragmenter("./assets/day_9_disk_input");
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
use super::{utils::read_disk_map_input, DiskMap};
|
|
||||||
|
|
||||||
pub fn disk_fragmenter(input: &str) -> usize {
|
|
||||||
let disk_map = read_disk_map_input(input);
|
|
||||||
|
|
||||||
let organized_disk_map = organize_disk_map(&disk_map);
|
|
||||||
println!("{:?}", disk_map);
|
|
||||||
println!("{:?}", organized_disk_map);
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn organize_disk_map(disk_map: &DiskMap) -> DiskMap {
|
|
||||||
let organized_disk_map: DiskMap = vec![];
|
|
||||||
|
|
||||||
for block in disk_map {}
|
|
||||||
|
|
||||||
organized_disk_map
|
|
||||||
}
|
|
||||||
@@ -75,3 +75,33 @@ pub type AntinodeList = HashSet<Antinode>;
|
|||||||
// Disk fragmenter
|
// Disk fragmenter
|
||||||
pub type Block = Option<usize>;
|
pub type Block = Option<usize>;
|
||||||
pub type DiskMap = Vec<Block>;
|
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>;
|
||||||
|
|||||||
@@ -170,7 +170,8 @@ pub fn read_disk_map_input(input: &str) -> DiskMap {
|
|||||||
|
|
||||||
let mut id: usize = 0;
|
let mut id: usize = 0;
|
||||||
for (digit_index, char_digit) in raw_map.chars().enumerate() {
|
for (digit_index, char_digit) in raw_map.chars().enumerate() {
|
||||||
if let Some(digit) = char_digit.to_digit(10u32) {
|
if let Some(digit) = char_digit.to_digit(10) {
|
||||||
|
if digit > 0 {
|
||||||
for _ in 0..digit {
|
for _ in 0..digit {
|
||||||
if digit_index % 2 == 0 {
|
if digit_index % 2 == 0 {
|
||||||
disk_map.push(Some(id));
|
disk_map.push(Some(id));
|
||||||
@@ -183,10 +184,54 @@ pub fn read_disk_map_input(input: &str) -> DiskMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
disk_map
|
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
|
pub fn calc_distance<T>(num_1: T, num_2: T) -> T
|
||||||
where
|
where
|
||||||
T: PartialOrd + Sub<Output = T>,
|
T: PartialOrd + Sub<Output = T>,
|
||||||
|
|||||||
14
src/main.rs
14
src/main.rs
@@ -1,6 +1,18 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
// #![allow(dead_code)]
|
||||||
mod advent_of_code;
|
mod advent_of_code;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
advent_of_code::today();
|
let args: Vec<String> = env::args().collect();
|
||||||
|
println!("<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>");
|
||||||
|
println!(">>> Welcome to advent of code 2024 <<<");
|
||||||
|
println!("<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>");
|
||||||
|
if args.len() == 2 {
|
||||||
|
let day: u8 = args[1].parse().expect("Not a valid day.");
|
||||||
|
advent_of_code::today(day);
|
||||||
|
} else {
|
||||||
|
println!("Tell me a day!")
|
||||||
|
}
|
||||||
println!("Happy new year!");
|
println!("Happy new year!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user