Skip to content

Commit

Permalink
2024/07
Browse files Browse the repository at this point in the history
  • Loading branch information
encse committed Dec 7, 2024
1 parent 7cb4372 commit fb59680
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
4 changes: 4 additions & 0 deletions 2024/Day07/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ When you go to cross the bridge, you notice a group of engineers trying to repai
You ask how long it'll take; the engineers tell you that it only needs final calibrations, but some young elephants were playing nearby and <em>stole all the operators</em> from their calibration equations! They could finish the calibrations if only someone could determine which test values could possibly be produced by placing any combination of operators into their calibration equations (your puzzle input).

Read the [full puzzle](https://adventofcode.com/2024/day/7).

It's time to pull out the recursion guns. I introduced a checker logic that go through the numbers in one line of input and tries all possible operators on the accumulated result to reach the target.

The common logic that parses the input and executes the checker was extracted into a single `Solve` function, but I found it more readable to have distinct checkers for the two parts of the problem. Everything runs in about a second, but since it's just a single line, I added an optimization in `Check2` to exit early when the accumulated result exceeds the target.
11 changes: 8 additions & 3 deletions 2024/Day07/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Solution : Solver {
public object PartOne(string input) => Filter(input, Check1).Sum();
public object PartTwo(string input) => Filter(input, Check2).Sum();

// returns those calibrations returns that are valid according to the checker
private IEnumerable<long> Filter(string input, Func<long,long,List<long>, bool> check) =>
from line in input.Split("\n")
let parts = Regex.Matches(line, @"\d+").Select(m=>long.Parse(m.Value))
Expand All @@ -19,6 +20,9 @@ from line in input.Split("\n")
where check(target, 0, nums)
select target;

// separate checkers provided for the two parts, these recursive functions go
// over the numbers and use all alloved operators to update the accumulated result
// at the end of the recursion we simply check if we reached the target
private bool Check1(long target, long acc, List<long> nums) =>
nums switch {
[] => target == acc,
Expand All @@ -28,9 +32,10 @@ private bool Check1(long target, long acc, List<long> nums) =>

private bool Check2(long target, long acc, List<long> nums) =>
nums switch {
_ when acc > target => false, // optimization: early exit from deadend
[] => target == acc,
_ => Check2(target, acc * nums[0], nums[1..]) ||
Check2(target, acc + nums[0], nums[1..]) ||
Check2(target, long.Parse($"{acc}{nums[0]}"), nums[1..])
_ => Check2(target, long.Parse($"{acc}{nums[0]}"), nums[1..]) ||
Check2(target, acc * nums[0], nums[1..]) ||
Check2(target, acc + nums[0], nums[1..])
};
}

0 comments on commit fb59680

Please sign in to comment.