Split at each operator, solve both sides, combine every pair. The same sides come up again and again.
Whatever the bracketing, one operator is applied last, and it splits the expression into a left part and a right part. The code tries every operator in that role. Each row below is one call; rows shaded red are substrings that were already solved earlier, and get solved again from scratch.
Press Next to start.
Bracket 2*3-4*5 any way you like: one operator is evaluated last, and everything to its left is one complete sub-expression, everything to its right another. So the answers are exactly: for each operator, every value of the left side combined with every value of the right side. That's the whole recursion. Each side is the same problem, smaller.
The operator done last splits the problem in two.
Step through 2*3-4*5 and watch the red rows: "3" and "4" are each solved five times, "2*3" and "4*5" twice. Pick 1+1+1+1 and almost every row is red: 27 calls for only 4 different substrings. Every repeat recomputes exactly the same list of values. Storing each substring's answer the first time it's solved would answer every repeat instantly. That's Sunday's checkpoint, and the whole idea of Week 5.