0. Since a triangular number is ( n^2 + n ) / 2 and that
can be expressed in the quadratic formula, it is easy to
determine if a number is triangular or not
1. The code determines if the target is a triangular number.
As a side effect, if it is not a triangular number it
returns the largest triangular number smaller than the
target (p is short for previous)
2. It then determines the difference between the target and
the previous triangular number and does a divide and conquer
approach - for instance, if the difference was 6
0 6
1 5
2 4
3 3
3. If it finds 2 new targets that are both triangular,
it returns. If it doesn't it just drops down to the
previous number and starts the process again
Incidently, I do not think (haven't tested) this approach
will benefit that much from caching known triangular numbers.
It was pretty fast no matter what numbers I threw at it and
it would chew up memory pretty quickly.