diff --git a/input/day7_custom.test.txt b/input/day7_custom.test.txt new file mode 100644 index 0000000..042be7e --- /dev/null +++ b/input/day7_custom.test.txt @@ -0,0 +1,4 @@ +12345: 12 34 5 +12034050: 120 340 50 +15: 1 2 3 4 5 +120: 1 2 3 4 5 \ No newline at end of file diff --git a/src/day7.rs b/src/day7.rs index 12445db..b2e8106 100644 --- a/src/day7.rs +++ b/src/day7.rs @@ -1,9 +1,83 @@ pub fn day7_part1(input: &str) -> String { let input = parse(input); - let sum: u64 = input.into_iter().filter(|(res, operands)| possible(*res, operands)).map(|(res, _)| res).sum(); + let sum: u64 = input + .into_iter() + .filter(|(res, operands)| possible(*res, operands)) + .map(|(res, _)| res) + .sum(); sum.to_string() } +pub fn day7_part2(input: &str) -> String { + let input = parse(input); + let sum: u64 = input + .into_iter() + .filter(|(res, operands)| possible_with_concatenation(*res, operands)) + .map(|(res, _)| res) + .sum(); + sum.to_string() +} + +fn possible_with_concatenation(res: u64, operands: &[u64]) -> bool { + let operator_count = operands.len() - 1; + let possibilities = 0..(3u64.pow(operator_count as u32)); + for possibility in possibilities { + if evaluate_with_concatenation(possibility, operands) == res { + return true; + } + } + dbg!(res); + false +} + +fn evaluate_with_concatenation(mut bitpattern: u64, operands: &[u64]) -> u64 { + // dbg!(bitpattern, operands); + let selected_option = bitpattern % 3; + let mut result = if selected_option == 0 { + operands[0] + operands[1] + } else if selected_option == 1 { + operands[0] * operands[1] + } else { + concatenate(operands[0], operands[1]) + }; + + let mut debug_operators = vec![]; + + for operator in 2..operands.len() { + bitpattern /= 3; + let selected_option = bitpattern % 3; + + result = if selected_option == 0 { + result + operands[operator] + } else if selected_option == 1 { + result * operands[operator] + } else { + concatenate(result, operands[operator]) + }; + + debug_operators.push(if selected_option == 0 { + '+' + } else if selected_option == 1 { + '*' + } else { + '|' + }); + } + + // dbg!(result, bitpattern, debug_operators); + result +} + +fn concatenate(left: u64, right: u64) -> u64 { + let decimal_places_shift = (right as f64).log10().ceil() as u32; + left * 10u64.pow(decimal_places_shift) + right +} + +#[test] +fn test_concatenate() { + assert_eq!(concatenate(15, 6), 156) +} + fn possible(res: u64, operands: &[u64]) -> bool { // dbg!(res, operands); let operator_count = operands.len() - 1; @@ -13,7 +87,7 @@ fn possible(res: u64, operands: &[u64]) -> bool { return true; } } - + false } @@ -41,7 +115,7 @@ fn evaluate(bitpattern: u64, operands: &[u64]) -> u64 { #[derive(Copy, Clone, Eq, PartialEq, Debug)] enum Operator { Times, - Plus + Plus, } fn parse(input: &str) -> Vec<(u64, Vec)> { diff --git a/src/lib.rs b/src/lib.rs index 57a8f40..84761ac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -356,6 +356,19 @@ mod tests { assert_eq!(result, "3598800864292"); } + // #[ignore] + #[test] + fn day7_part2_test() { + // let simple_result = day7::day7_part2(include_str!("../input/day7_custom.test.txt")); + // assert_eq!(simple_result, (12345 + 12034050 + 15 + 120).to_string()); + + // let test_result = day7::day7_part2(include_str!("../input/day7.test.txt")); + // assert_eq!(test_result, "11387"); + let result = day7::day7_part2(include_str!("../input/day7.txt")); + let parsed_result: u64 = result.parse::().unwrap(); + assert!(parsed_result > 318_910_516_761_637, "{parsed_result} was too low"); + } + #[test] fn day6_part1_test() { let test_result = day6::day6_part1(include_str!("../input/day6.test.txt"));