In those cases, you may wish to use a dynamic programming technique. A bit of caching might be a greater optimization than tail call elimination. The `@functools.lru_cache` tool is very easy to experiment with.
They made a highly redundant traceback display much more pleasant a couple years ago, writing "the same thing 1,998 more times ..." or something like that.