day 23 optimize, with help
Shamelessly port the DP approach from askalski into m4 (see the link
in the code). The dynamic programming solution is WAY faster than any
DFS pruning, by exploiting the maximum tree-width into a bounded
linear amount of work per row. Each row is processed in isolation and
computes the set of all possible downward exits that still form a
valid string of balanced and nested pairs of path components; since
there are a limited number of such strings, pruning is as simple as
rejecting the attempts that don't produce a valid exit string. This
cuts the solution time to 315ms.
My original DFS solution is still available via -Dalgo=dfs.