Exponents / Iteration vs Recursion
def pow_interative(x, n):
res = x
for i in range(1, n):
res = res * x
return res
def pow_recursive(x, n):
if n == 0:
return 1
res = pow_recursive(x, n-1) * x
return res
assert pow_interative(2, 2) == 4
assert pow_recursive(3, 3) == 27
print("2^2 =", pow_interative(2,2))
print("3^3 =", pow_recursive(3,3))
import time
t1 = time.time(); result = pow_interative(3, 600)
t2 = time.time(); result = pow_recursive(3, 600)
t4 = time.time(); result = pow(3, 600)
print("Iterative 3^600: ", time.time() - t1, 's')
print("Recursive 3^600: ", time.time() - t2, 'sec')
print("Native pow 3^600: ", time.time() - t4, 's')
Factorial / Iteration vs Recursion
def factorial_iterative(n):
p = 1
for i in range(1, n+1):
p = p * i
return p
def factorial_recursive(n):
if n == 1:
return 1
return n * factorial_recursive(n-1)
assert factorial_iterative(4) == 24
assert factorial_recursive(5) == 5 * factorial_recursive(4)
print("4! =", factorial_iterative(4))
print("5! =", factorial_recursive(5))
n = factorial_iterative(30000)
print(f"Iterative factorial 30.000 iterations:", len(str(n)))
try:
n = factorial_recursive(3000)
except RecursionError as e:
print(f"Recursive factorial 3.000 iterations limit reached!")
print(f"RecursionError: {e}")
Fibonacci / Iteration vs Recursion
Every number is the sum of previous two numbers.
def fibonacci_iterative(n):
a, b = 0, 1
for i in range(1, n):
nextb = a + b
a = b
b = nextb
return b
def fibonacci_recursive(n):
if n <= 2:
return 1
return fibonacci_recursive(n-1) + fibonacci_recursive(n-2)
assert fibonacci_iterative(1) == 1
assert fibonacci_iterative(3) == 2
assert fibonacci_iterative(4) == 3
assert fibonacci_iterative(5) == 5
assert fibonacci_recursive(6) == 8
assert fibonacci_recursive(7) == 13
print("The third Fibonnaci number is:", fibonacci_iterative(3))
print("The forth Fibonnaci number is:", fibonacci_iterative(4))
print("The fifth Fibonnaci number is:", fibonacci_iterative(5))
import time
print("\nThe recursive algorithm is much slower than the iterative.")
print("Processing ...")
t1 = time.time(); n1 = fibonacci_iterative(100)
t2 = time.time(); n2 = fibonacci_recursive(36)
print("Iterative: fibonacci(100)", time.time() - t1, 's')
print("Recursive: fibonacci(36) ", time.time() - t2, 's')
Logarithm
Use binary search (divide and conquer) to compute logarithm.
import math
def logarithm(x, base):
if x == 1:
return 0
left = 0
right = x
epsilon = 1e-7
m = (right + left) // 2
while right - left > epsilon:
if x <= base**m:
right = m
else:
left = m
m = (left + right) / 2
return round(m, 7)
print(logarithm(8, 2))
print(logarithm(625, 5))
print(logarithm(1000, 10))
assert logarithm(8, 2) == 3 == math.log(8, 2)
assert logarithm(625, 5) == 4 == math.log(625, 5)
assert logarithm(1000, 10) == 3 == round(math.log(1000, 10))