diff --git a/Cargo.lock b/Cargo.lock index a45f174..4712019 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ version = 3 name = "advent-of-code-2024" version = "0.1.0" dependencies = [ + "primes", "regex", ] @@ -24,6 +25,12 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "primes" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0466ef49edd4a5a4bc9d62804a34e89366810bd8bfc3ed537101e3d099f245c5" + [[package]] name = "regex" version = "1.11.1" diff --git a/Cargo.toml b/Cargo.toml index 3f298fa..6b97431 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" edition = "2021" [dependencies] +primes = "0.4.0" regex = "1.11.1" diff --git a/README.md b/README.md index 4d18f04..f564d0f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ https://adventofcode.com/2024 | 04 | Ceres Search | :pushpin: | :pushpin: | Matrix multidirectional search | | 05 | Print Queue | :pushpin: | :pushpin: | Queue order | | 06 | Guard Gallivant | :pushpin: | :pushpin: | 2D navigation | -| 07 | | | | | +| 07 | Bridge Repair | | | Equation parsing | | 08 | | | | | | 09 | | | | | | 10 | | | | | diff --git a/assets/day_7_calibrations_input b/assets/day_7_calibrations_input new file mode 100644 index 0000000..fc6e099 --- /dev/null +++ b/assets/day_7_calibrations_input @@ -0,0 +1,9 @@ +190: 10 19 +3267: 81 40 27 +83: 17 5 +156: 15 6 +7290: 6 8 6 15 +161011: 16 10 13 +192: 17 8 14 +21037: 9 7 18 13 +292: 11 6 16 20 diff --git a/src/advent_of_code/mod.rs b/src/advent_of_code/mod.rs index 082ff57..210d401 100644 --- a/src/advent_of_code/mod.rs +++ b/src/advent_of_code/mod.rs @@ -1,11 +1,12 @@ -mod fri_06; -mod mon_02; -mod sun_01; -mod thu_05; -mod tue_03; +// mod fri_06; +// mod mon_02; +// mod sun_01; +// mod thu_05; +// mod tue_03; +// mod wed_04; +mod sat_07; mod types; mod utils; -mod wed_04; use types::*; @@ -50,8 +51,12 @@ pub fn historian_hysteria() { // 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); + // 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); } diff --git a/src/advent_of_code/sat_07.rs b/src/advent_of_code/sat_07.rs new file mode 100644 index 0000000..104d6df --- /dev/null +++ b/src/advent_of_code/sat_07.rs @@ -0,0 +1,83 @@ +use primes::{PrimeSet, Sieve}; + +use super::*; + +pub fn bridge_repair(input: &str) -> CalibrationResult { + let equation_vec = utils::read_calibration_equations(input); + let mut sum_result: CalibrationResult = 0; + + for equation in equation_vec { + if is_equation_true(&equation) { + sum_result += equation.0; + } + } + + sum_result +} + +pub fn is_equation_true(equation: &Calibration) -> bool { + let operation_variants = generate_operation_variants(equation.1.len() as u32 - 1); + + for variant in operation_variants { + let mut local_operands = equation.1.clone(); + local_operands.reverse(); + let result = calc_operation(local_operands, variant); + if result == equation.0 { + return true; + } + } + + false +} + +// FIXME: this goes wrong on large numbers +pub fn generate_operation_variants(count: u32) -> Vec> { + let mut variant_list: Vec> = vec![]; + + let mut pset = Sieve::new(); // get prime numbers + + let variant_num = 2i32.pow(count); + + for variant_index in 0..variant_num { + let mut new_vec: Vec = vec![]; + for new_operand_index in 0..count { + match variant_index as u64 % pset.get(new_operand_index as usize) { + 0 => new_vec.push(Operation::MUL), + _ => new_vec.push(Operation::SUM), + } + } + variant_list.push(new_vec); + } + + variant_list +} + +pub fn calc_operation( + operands: CalibrationEquation, + operators: Vec, +) -> CalibrationResult { + if operands.len() == 2 { + return operate(&operands[0], &operands[1], &operators[0]); + } + + return operate( + &operands[0], + &calc_operation(operands[1..].to_vec(), operators[1..].to_vec()), + &operators[0], + ); +} + +pub fn operate( + first: &CalibrationResult, + second: &CalibrationResult, + operation: &Operation, +) -> CalibrationResult { + match operation { + Operation::SUM => { + return first + second; + } + Operation::MUL => { + return first * second; + } + } +} diff --git a/src/advent_of_code/types.rs b/src/advent_of_code/types.rs index 47998ca..3089f3e 100644 --- a/src/advent_of_code/types.rs +++ b/src/advent_of_code/types.rs @@ -45,3 +45,14 @@ pub struct Guard { pub y: usize, pub dir: Direction, } + +// Bridge repair +pub type CalibrationResult = u128; +pub type CalibrationEquation = Vec; +pub struct Calibration(pub CalibrationResult, pub CalibrationEquation); + +#[derive(Debug, Clone, Copy)] +pub enum Operation { + SUM, + MUL, +} diff --git a/src/advent_of_code/utils.rs b/src/advent_of_code/utils.rs index a070977..815fa0d 100644 --- a/src/advent_of_code/utils.rs +++ b/src/advent_of_code/utils.rs @@ -125,6 +125,25 @@ pub fn read_floor_map_and_guard_input(input: &str) -> (Guard, FloorMap) { (the_guard, floor_map) } +pub fn read_calibration_equations(input: &str) -> Vec { + let mut calibration_list: Vec = vec![]; + + for line in read_to_string(input).unwrap().lines() { + if let Some((test_value, equation_values)) = line.split_once(": ") { + let mut values: CalibrationEquation = vec![]; + for equation_value in equation_values.split(" ") { + values.push(equation_value.parse::().unwrap()); + } + calibration_list.push(Calibration( + test_value.parse::().unwrap(), + values, + )); + } + } + + calibration_list +} + pub fn calc_distance(num_1: T, num_2: T) -> T where T: PartialOrd + Sub,