From 57ed9d261e9aeac221ece30766ae8f46a2aa7ca8 Mon Sep 17 00:00:00 2001 From: Parnic Date: Sat, 7 Dec 2024 10:50:59 -0600 Subject: [PATCH] Day 7 optimization Okay, this optimization was easier than I thought it'd be. I started by not building a new list every time I wanted to operate on the next value since that seemed like low-hanging fruit. That helped, but not as much as I expected (as is always the case with optimization, I feel). Next I ran this under a profiler and it showed that string concatenation was the biggest offender, so I found a way to do that without involving strings (it's a bit convoluted, but optimizations tend to do that...) and that cleaned up most of the problem. After that, getting the next element from the list was a (very minor) next-highest offender, so I cached that locally. Finally, on a whim I decided that the tuple wasn't helping me anymore, so I removed it and was surprised to see another 100ms or so disappear. I guess constructing those is worse than I thought...gotta file that away for later. I'm a little surprised that it didn't show up in the profiler (or I didn't know how to read it, perhaps). --- src/07.cs | 41 +++++++++++++++++++++++------------------ src/Util/NumConcat.cs | 29 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 src/Util/NumConcat.cs diff --git a/src/07.cs b/src/07.cs index 0fc3200..43c96c7 100644 --- a/src/07.cs +++ b/src/07.cs @@ -1,4 +1,6 @@ -namespace aoc2024; +using aoc2024.Util; + +namespace aoc2024; internal class Day07 : Day { @@ -14,42 +16,45 @@ internal class Day07 : Day } } - private static bool CanSolveAddMult((long result, List inputs) eq) + private static bool CanSolveAddMult(long target, long current, List inputs, int idx) { - if (eq.inputs.Count > 2) + if (idx == inputs.Count) { - var added = eq.inputs[0] + eq.inputs[1]; - var multd = eq.inputs[0] * eq.inputs[1]; - return CanSolveAddMult(eq with { inputs = [added, .. eq.inputs.Skip(2)] }) || CanSolveAddMult(eq with { inputs = [multd, .. eq.inputs.Skip(2)] }); + return current == target; } - return eq.inputs[0] + eq.inputs[1] == eq.result || eq.inputs[0] * eq.inputs[1] == eq.result; + var next = inputs[idx]; + var added = current + next; + var multd = current * next; + return CanSolveAddMult(target, added, inputs, idx + 1) || + CanSolveAddMult(target, multd, inputs, idx + 1); } internal override string Part1() { - long total = eqs.Where(CanSolveAddMult).Sum(eq => eq.result); + long total = eqs.Where(eq => CanSolveAddMult(eq.result, eq.inputs[0], eq.inputs, 1)).Sum(eq => eq.result); return $"Add | Mult calibration result: <+white>{total}"; } - private static bool CanSolveAddMultConcat((long result, List inputs) eq) + private static bool CanSolveAddMultConcat(long target, long current, List inputs, int idx) { - if (eq.inputs.Count > 2) + if (idx == inputs.Count) { - var added = eq.inputs[0] + eq.inputs[1]; - var multd = eq.inputs[0] * eq.inputs[1]; - var cated = long.Parse($"{eq.inputs[0]}{eq.inputs[1]}"); - return CanSolveAddMultConcat(eq with { inputs = [added, .. eq.inputs.Skip(2)] }) - || CanSolveAddMultConcat(eq with { inputs = [multd, .. eq.inputs.Skip(2)] }) - || CanSolveAddMultConcat(eq with { inputs = [cated, .. eq.inputs.Skip(2)] }); + return current == target; } - return eq.inputs[0] + eq.inputs[1] == eq.result || eq.inputs[0] * eq.inputs[1] == eq.result || long.Parse($"{eq.inputs[0]}{eq.inputs[1]}") == eq.result; + var next = inputs[idx]; + var added = current + next; + var multd = current * next; + var cated = NumConcat.Longs(current, next); + return CanSolveAddMultConcat(target, added, inputs, idx + 1) || + CanSolveAddMultConcat(target, multd, inputs, idx + 1) || + CanSolveAddMultConcat(target, cated, inputs, idx + 1); } internal override string Part2() { - long total = eqs.Where(CanSolveAddMultConcat).Sum(eq => eq.result); + long total = eqs.Where(eq => CanSolveAddMultConcat(eq.result, eq.inputs[0], eq.inputs, 1)).Sum(eq => eq.result); return $"Add | Mult | Concat calibration result: <+white>{total}"; } } diff --git a/src/Util/NumConcat.cs b/src/Util/NumConcat.cs new file mode 100644 index 0000000..f3c92b2 --- /dev/null +++ b/src/Util/NumConcat.cs @@ -0,0 +1,29 @@ +namespace aoc2024.Util; + +public static class NumConcat +{ + public static long Longs(long a, long b) + { + return b switch + { + < 10 => 10L * a + b, + < 100 => 100L * a + b, + < 1000 => 1000L * a + b, + < 10000 => 10000L * a + b, + < 100000 => 100000L * a + b, + < 1000000 => 1000000L * a + b, + < 10000000 => 10000000L * a + b, + < 100000000 => 100000000L * a + b, + < 1000000000 => 1000000000L * a + b, + < 10000000000 => 10000000000L * a + b, + < 100000000000 => 100000000000L * a + b, + < 1000000000000 => 1000000000000L * a + b, + < 10000000000000 => 10000000000000L * a + b, + < 100000000000000 => 100000000000000L * a + b, + < 1000000000000000 => 1000000000000000L * a + b, + < 10000000000000000 => 10000000000000000L * a + b, + < 100000000000000000 => 100000000000000000L * a + b, + _ => 1000000000000000000L * a + b + }; + } +}