Skip to content
Advertisement

Convert a recursive python code to a non-recursive version

The code provided here works unless we start to increase the distinct and n-symbols and length, for example, on my computer n_symbols=512, length=512, distinct=300 ends up with this error RecursionError: maximum recursion depth exceeded in comparison and then overflow errors if I increase the lru_cache value.
What I want is to have a non-recursive version of this code.

JavaScript

Then

JavaScript

runs in ~0.5 second giving the answer

JavaScript

Advertisement

Answer

Here’s mine:

JavaScript

Speed comparison for some argument sets:

JavaScript

In my last line you see I split the overall result into three factors:

  • comb(n_symbols, distinct) for choosing which distinct out of the n_symbols symbols actually get used. That essentially gets rid of the n_symbols parameter, or think of it as compensating setting n_symbols = distinct.
  • factorial(distinct) for the order in which the symbols get used first. This gets rid of the * (n_symbols - used) in your recurrence.
  • ways[distinct] is the number of ways to build a sequence of length length with exactly distinct distinct symbols, where the order in which they get used first is fixed.

It might be easier to think of the ways table as two-dimensional: ways[length][distinct]. But for more memory-efficiency, I compute it row by row and only keep the latest row.

Benchmark and some correctness checks (Try it online!):

JavaScript
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement