0

How do you evaluate how many times some loops will run, when you start to complicate the boundaries conditions? For example, take this function:

def f(n):
    s = 0
    for i in range(n):
        for j in range(i, (n + i**2) // (n - i) + 1):
            s += 1
    return s

for i in range(10):
    print(i, "->", f(i))

Output:

0 -> 0
1 -> 2
2 -> 5
3 -> 10
4 -> 17
5 -> 28
6 -> 42
7 -> 60
8 -> 83
9 -> 109
```
user1000
  • 1
  • 1
  • I hate to redirect you again, but this honestly seems more like a math question than a CS one…it comes down to "how can I evaluate this sum in the general case?". But I'll wait and see if people here think it's on-topic or not. – Draconis Aug 21 '19 at 04:09

1 Answers1

1

If you approximate this as an integral of the second for loop you get, substituting $k=(n-i)$:

$$I_n = \int_1^n \frac{n+(n-k)^2-(n-k)+1}{k} dk = \int_1^n 1+\frac{(n-k)^2+1}{k} dk$$

according to WA, the corresponding antiderivative is of the indefinite integral is:

$$(n^2+1)log(k) + \frac{1}{2}k(k-4n+2) +C$$

Thus, evaluating at $k=1$ and $n$ we get:

$$I_n = (n^2+1)log(n)+\frac{-3+6n-3n^2}{2}$$

So, the discrete sum should approximately reflex that. I graphed it out on desmos, and it seems to show that the exact error grows infinitely, they are asymptotically equal.

Zach Hunter
  • 395
  • 1
  • 14