mirror of
https://github.com/parnic/advent-of-code-2024.git
synced 2025-06-16 12:30:13 -05:00
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).
This commit is contained in:
41
src/07.cs
41
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<long> inputs) eq)
|
||||
private static bool CanSolveAddMult(long target, long current, List<long> 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<long> inputs) eq)
|
||||
private static bool CanSolveAddMultConcat(long target, long current, List<long> 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}";
|
||||
}
|
||||
}
|
||||
|
29
src/Util/NumConcat.cs
Normal file
29
src/Util/NumConcat.cs
Normal file
@ -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
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user