2024-12-10 16:21:17 +00:00
|
|
|
advent_of_code::solution!(7);
|
|
|
|
|
|
|
|
|
|
pub fn part_one(input: &str) -> Option<usize> {
|
|
|
|
|
let total: usize = input.lines().filter_map(|line| {
|
|
|
|
|
// println!("{line}");
|
|
|
|
|
let m: Vec<&str> = line.split(": ").collect();
|
|
|
|
|
let total = m[0].parse::<usize>().unwrap();
|
|
|
|
|
let values: Vec<usize> = m[1].split(' ').map(|v| v.parse::<usize>().unwrap()).collect();
|
|
|
|
|
|
|
|
|
|
// println!("LINE: {} = {:?}", total, values);
|
|
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
if can_calc(total, &values) { Some(total) } else { None }
|
2024-12-10 16:21:17 +00:00
|
|
|
// Some(total)
|
|
|
|
|
}).sum();
|
|
|
|
|
// println!("TOTAL: {}", total);
|
|
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
Some(total)
|
2024-12-10 16:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-17 21:42:16 +00:00
|
|
|
pub fn part_two(input: &str) -> Option<usize> {
|
|
|
|
|
let total: usize = input.lines().filter_map(|line| {
|
|
|
|
|
// println!("{line}");
|
|
|
|
|
let m: Vec<&str> = line.split(": ").collect();
|
|
|
|
|
let total = m[0].parse::<usize>().unwrap();
|
|
|
|
|
let values: Vec<usize> = m[1].split(' ').map(|v| v.parse::<usize>().unwrap()).collect();
|
|
|
|
|
|
|
|
|
|
// println!("LINE: {} = {:?}", total, values);
|
|
|
|
|
|
|
|
|
|
if can_calc_2(total, &values) { Some(total) } else { None }
|
|
|
|
|
// Some(total)
|
|
|
|
|
}).sum();
|
|
|
|
|
// println!("TOTAL: {}", total);
|
|
|
|
|
|
|
|
|
|
Some(total)
|
2024-12-10 16:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allowed operators: + and *
|
|
|
|
|
// all possible options OP^(values count - 1)
|
|
|
|
|
// eg 190: 10 19 -- has TWO possible paths, 10 + 19 and 10 * 19
|
|
|
|
|
// eg 123: 4 5 6 3 -- has 8 possible paths; 4+5+6+3, 4+5+6*3, ... 4*5*6*3
|
|
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
fn can_calc(total: usize, values: &[usize]) -> bool {
|
|
|
|
|
let is_valid = values.iter().fold(vec![0_usize], |subtotals, next_value| {
|
2024-12-10 16:21:17 +00:00
|
|
|
process(&subtotals, next_value)
|
|
|
|
|
}).iter().any(|t| *t == total);
|
|
|
|
|
|
|
|
|
|
is_valid
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
fn process(sum: &[usize], next_value: &usize) -> Vec<usize> {
|
|
|
|
|
sum.iter().flat_map(|v| {
|
2024-12-10 16:21:17 +00:00
|
|
|
vec![v + next_value, v * next_value]
|
|
|
|
|
}).collect()
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-17 21:42:16 +00:00
|
|
|
fn can_calc_2(total: usize, values: &[usize]) -> bool {
|
|
|
|
|
let is_valid = values.iter().fold(vec![0_usize], |subtotals, next_value| {
|
|
|
|
|
process_2(&subtotals, next_value)
|
|
|
|
|
}).iter().any(|t| *t == total);
|
|
|
|
|
|
|
|
|
|
is_valid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn process_2(sum: &[usize], next_value: &usize) -> Vec<usize> {
|
|
|
|
|
sum.iter().flat_map(|v| {
|
|
|
|
|
let concat_val = (v.to_string() + next_value.to_string().as_str()).parse::<usize>().unwrap();
|
|
|
|
|
vec![v + next_value, v * next_value, concat_val]
|
|
|
|
|
}).collect()
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-10 16:21:17 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_process() {
|
2024-12-13 17:03:17 +00:00
|
|
|
let sum = [1];
|
2024-12-10 16:21:17 +00:00
|
|
|
let next_value = 10;
|
|
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
let result = process(&sum, &next_value);
|
2024-12-10 16:21:17 +00:00
|
|
|
assert_eq!(result, vec![11, 10]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_can_calc() {
|
2024-12-13 17:03:17 +00:00
|
|
|
let values = [1,2,3,4];
|
|
|
|
|
let total = 10;
|
2024-12-10 16:21:17 +00:00
|
|
|
|
2024-12-13 17:03:17 +00:00
|
|
|
let result = can_calc(total, &values);
|
2024-12-10 16:21:17 +00:00
|
|
|
assert_eq!(result, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_part_one() {
|
|
|
|
|
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
|
|
|
|
assert_eq!(result, Some(3749));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_part_two() {
|
2024-12-17 21:42:16 +00:00
|
|
|
let result: Option<usize> = part_two(&advent_of_code::template::read_file("examples", DAY));
|
|
|
|
|
assert_eq!(result, Some(11387));
|
2024-12-10 16:21:17 +00:00
|
|
|
}
|
|
|
|
|
}
|