diff --git a/src/day07.rs b/src/day07.rs index 0c78ed2..5dcf05f 100644 --- a/src/day07.rs +++ b/src/day07.rs @@ -22,15 +22,15 @@ fn part1(input: &str) -> RiddleResult { .map(|capture| capture.as_str().parse::().unwrap()) .collect_vec() }) - .filter(well_calibrated) + .filter(|v| well_calibrated(v, false)) .map(|v| v[0]) .sum() } -fn well_calibrated(list: &Vec) -> bool { +fn well_calibrated(list: &Vec, concat: bool) -> bool { let expected = list[0]; let operands = list.iter().skip(1).copied().collect_vec(); - let operators = ops(operands.len() - 1); + let operators = ops(operands.len() - 1, concat); for ops in operators.into_iter() { // dbg!(&ops); let v = ops @@ -39,6 +39,7 @@ fn well_calibrated(list: &Vec) -> bool { .fold(operands[0], |acc, (op, val)| match op { '*' => acc * val, '+' => acc + val, + '|' => format!("{acc}{val}").parse().unwrap(), _ => panic!(), }); if v == expected { @@ -48,24 +49,80 @@ fn well_calibrated(list: &Vec) -> bool { false } -fn ops(n: usize) -> Vec> { +fn ops(n: usize, concat: bool) -> Vec> { if n == 1 { - return vec![vec!['+'], vec!['*']]; + let mut v = vec![vec!['+'], vec!['*']]; + if concat { + v.push(vec!['|']); + } + return v; } - let v = ops(n - 1); + let v = ops(n - 1, concat); v.into_iter() .flat_map(|vector| { - let mut v1 = vector.clone(); - let mut v2 = vector; - v1.push('+'); - v2.push('*'); - [v1, v2] + if !concat { + let mut v1 = vector.clone(); + let mut v2 = vector; + v1.push('+'); + v2.push('*'); + + vec![v1, v2] + } else { + let mut v1 = vector.clone(); + let mut v2 = vector.clone(); + let mut v3 = vector.clone(); + let mut v4 = vector.clone(); + let mut v5 = vector.clone(); + let mut v6 = vector.clone(); + let mut v7 = vector.clone(); + let mut v8 = vector.clone(); + let mut v9 = vector; + v1.push('+'); + v2.push('+'); + v3.push('+'); + v4.push('*'); + v5.push('*'); + v6.push('*'); + v7.push('|'); + v8.push('|'); + v9.push('|'); + + vec![v1, v2, v3, v4, v5, v6, v7, v8, v9] + } }) .collect_vec() } -fn part2(_input: &str) -> RiddleResult { - 0 +fn part2(input: &str) -> RiddleResult { + let regex = Regex::new("(\\d+)").unwrap(); + input + .lines() + .map(|line| { + regex + .find_iter(line) + .map(|capture| capture.as_str().parse::().unwrap()) + .collect_vec() + }) + .filter(|v| well(v[0], v[1], &v[2..])) + .map(|v| v[0]) + .sum() +} + +fn well(expected: i64, acc: i64, operands: &[i64]) -> bool { + if operands.is_empty() { + return expected == acc; + } + + let next = operands[0]; + let remainder = &operands[1..]; + + let v_mul = acc * next; + let v_plus = acc + next; + let v_concat = format!("{acc}{next}").parse().unwrap(); + well(expected, v_mul, remainder) + || well(expected, v_plus, remainder) + || well(expected, v_concat, remainder) + // _ => panic!(), } #[cfg(test)] @@ -89,6 +146,6 @@ mod test { #[test] fn test2() { - assert_eq!(part2(TEST_INPUT), 0); + assert_eq!(part2(TEST_INPUT), 11387); } }