0% found this document useful (0 votes)
48 views

CS1010S-Lec-03 Recursion, Iteration

The document discusses recursion, iteration, and provides examples to explain the concepts. It covers recursive and iterative solutions for factorial, exponentiation, and Fibonacci problems. The document also discusses ingredients for recursion like base case and recursive step.

Uploaded by

Akane Yori
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views

CS1010S-Lec-03 Recursion, Iteration

The document discusses recursion, iteration, and provides examples to explain the concepts. It covers recursive and iterative solutions for factorial, exponentiation, and Fibonacci problems. The document also discusses ingredients for recursion like base case and recursive step.

Uploaded by

Akane Yori
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

CS1010S Programming Methodology

Lecture 3
Recursion, Iteration

30 Aug 2023
Admin Matters
- Contest in the next week
- Once you start, you should finish within 90 mins.
- Consider it as a prep for the midterm exam.

- The contest will be open from 10am to 4pm on Sat 9th Oct
- If you are unable to attempt in this time window, let us know by
this Saturday 2359.

- Do not plagiarise!
Don’t pay for
notes/exam
papers!
NUS Course Material
Ethical Behaviour and Respecting Copyright

All course participants (including permitted guest students) who have access to the course
materials on LumiNUS or any approved platforms by NUS for delivery of NUS modules are not
allowed to re-distribute the contents in any forms to third parties without the explicit consent
from the module instructors or authorized NUS officials
Examples of what is disallowed
• No posting on any websites (except otherwise explicitly allowed)
• No selling of material
• No sharing of questions/answers which could lead to cheating/plagiarism
Recap

Inputs Function Output


Learning Outcomes
After this lesson, you should be able to
• know how apply divide and conquer technique to solve a
problem
• differentiate between recursion and iteration
Example 1: Factorial (𝑛 − 1)!
Consider the factorial function:
𝑛! = 𝑛 × 𝑛 − 1 × (𝑛 − 2) ⋯ × 1

Rewrite:
𝑛 × 𝑛−1 !, 𝑛 >1
𝑛! = ቊ
1, 𝑛=1
Factorial
𝑛 ×𝑓 𝑛−1 , 𝑛 >1
𝑓(𝑛) = ቊ
1, 𝑛=1

def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n – 1)
Recursion
def factorial(n):
if n == 1: terminating condition
return 1 (base case)
else:
return n * factorial(n – 1)

recursive call
Function that calls itself is called a recursive function
Ingredients for recursion
1. Base Case
Does involve a recursive call!
Has trivial answer

2. Recursive Step
Connects solution at to its subproblem!
def factorial(n):
if n == 1:
return 1
Recursive Factorial
else:
return n * fact(n – 1)
1
factorial(4)
deferred calls 1
factorial(4) 2
= 4 * factorial(3)
= 4 * 3 * factorial(2) 2
= 4 * 3 * 2 * factorial(1)
= 4 * 3 * 2 * (1) 3
= 4 * 3 * (2)
= 4 * (6) 6
= 24 24
4
Factorial: Another way! res = 1
counter = 1
res = 1
res = 1 * 2
res = 1 * 2 * 3
res = 1 * 2 * 3 * 4 F
counter <= n

T
def factorial(n):
res, counter = 1, 1
res = res * counter
while counter <= n:
res = res * counter
counter = counter + 1
return res counter = counter + 1
Iterative Process
res counter
def factorial(n):
1 1
res, counter = 1, 1
while counter <= n: 1 2
res = (res * counter) 2 3
counter = counter + 1 6 4
return res
24 5
factorial(5)

No deferred calls!
while loop while <expression>:
<while_body>

expression
Predicate (condition) to stay within the loop
F
<cond>

body T

Statement(s) that will be evaluated while_body

if predicate is True
outside
Yet another way! non-inclusive.
Up to n.
def factorial(n):
res = 1
for counter in range(2, n+1):
res = res * counter
return res

def factorial(n):
res, counter = 1, 1
while counter <= n:
res = res * counter
counter = counter + 1
return res
for loop for <var> in <sequence>:
<for_body>

sequence
a sequence of values
for each
var item in
seq
variable that take each value in the sequence
The seq
is over
body for_body
statement(s) that will be evaluated for outside
each value in the sequence
range function Examples

range([start,] stop[, step]) for i in range(10):


print(i)
• creates a sequence of integers
• from start (inclusive) to stop for i in range(3, 10):
(non-inclusive) print(i)
• incremented by step
for i in range(3, 10, 4):
print(i)
break
for j in range(10): 0
print(j) 1 for j in
2 [0…9]
if j == 3:
break 3 The seq
done is over
print("done") print(j)

F
j == 3

T
print(“done”)
continue
for j in range(10): 1 for j in
if j % 2 == 0: 3 [0…9]
continue 5
The seq
print(j) 7 T j is is over
print("done") 9 even
done F
print(j)

print(“done”)
Example 2: Exponentiation 𝑛𝑚−1
𝑛𝑚 = 𝑛 × 𝑛 × 𝑛 × … × 𝑛

Rewrite:
𝑛 × 𝑛𝑚−1 , 𝑚 > 0
𝑛𝑚 =ቊ
1, 𝑚=0
Exponentiation: Recursion
def power(n, m): def factorial(n):
if m == 0: if n == 0:
return 1 return 1
else: else:
return n * power(n, m – 1) return n * factorial(n – 1)

Notice any
similarity?
Exponentiation: Iteration
def power(n, m): def factorial(n):
res, counter = 1, 1 res, counter = 1, 1
while counter <= m: while counter <= n:
res = (res * counter)
res = res * n
counter = counter + 1
counter = counter + 1 return res
return res

power(2, 4) factorial(5)

res = 1 res = 1
res = 1 * 2 res = 1 * 2
res = 1 * 2 * 2 res = 1 * 2 * 3
res = 1 * 2 * 2 * 2 res = 1 * 2 * 3 * 4
res = 1 * 2 * 2 * 2 * 2 res = 1 * 2 * 3 * 4 * 5
Typical structure of recursion
def fn(n):
if <base_cond>:
return <base_val> Try to express the
else: problem in the
return <recur_formula> recursive way!
Examlple 3: Fibonacci Numbers
Leonardo Pisano Fibonacci (12th century) is credited for
the sequence:

0, 1, 1, 2, 3, 5, 8, 13, 21, …

Note: each number is the sum of the previous two.


Fibonacci in math
0, 𝑛=0
𝑓(𝑛) = ቐ 1, 𝑛=1
𝑓 𝑛 − 1 + 𝑓(𝑛 − 2) 𝑛 > 1
Fibonacci in Python
0, 𝑛=0
𝑓(𝑛) = ቐ 1, 𝑛=1
𝑓 𝑛 − 1 + 𝑓(𝑛 − 2) 𝑛 > 1
def fib(n):
if (n == 0):
return 0
elif (n == 1):
return 1
else:
return fib(n – 1) + fib(n – 2)
Recursion tree
fib(5)
root

fib(4) fib(3)

fib(3) fib(2) fib(2) fib(1)

fib(1) fib(1) fib(0) fib(1) fib(0) 1


fib(2)

1 1 0 1 0
fib(1) fib(0)

1 0

leaves
How about iteration?
def fib(n):
if (n == 0): a b c
a b c
return 0 0 1 1 2 3 5

elif (n == 1): a b c
a b
return 1
a, b = 0, 1
Observations:
while <cond>:
c = a + b
??? - Next a is current b
- Next b is current c
How about iteration?
def fib(n): Was this iteration
if (n == 0): as easy as
return 0 factorial/power?
elif (n == 1):
return 1
a, b = 0, 1
a, b = b, a + b
while n > 1:
# in this case answer is b
c = a + b
a = b
a, b = b, c
b = c
n = n – 1
return c
Questions
Recursive formula to count the number of digits in a
number.

Recursive formula to count the length of the string.


Example 4: Towers of Hanoi

Rules.
1. Can only put one disc at a time
2. Cannot put larger disc over a smaller disc
Towers of Hanoi

Rules.
1. Can only put one disc at a time
2. Cannot put larger disc over a smaller disc
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
Towers of Hanoi
A B C

Suppose we know how to move 3


discs from A to C
Towers of Hanoi
A B C

Suppose we know how to move 3


discs from A to C
Towers of Hanoi
A B C

Claim: we can move 3 discs from


A to B. Why?
Towers of Hanoi
A B C

Claim: we can move 3 discs from


A to B. Why?
Towers of Hanoi
A B C

How to move 4 discs?


1. Move 3 discs from A to B
2. Move 1 disc from A to C
Recursion
To move n discs from A to C (via B):
- Move n-1 discs from A to B (via C)
- Move the disc from A to C
- Move n-1 discs from B to C (via A)
Tower of Hanoi A C B
def move_tower(size, src, dest, aux):
if size == 0:
return True
else:
move_tower(size-1, src, aux, dest)
print_move(src, dest)
move_tower(size-1, aux, dest, src)

def print_move(src, dest):


print("move top disk from ", src," to ", dest)
Counting
Change
Problem

https://pollev.com/ashishdandekar
Counting Change Problem
How many ways to make change for $1, using
coins
50¢, 20¢, 10¢, 5¢, 1¢ (assuming unlimited number of coins)
e.g. 50¢ + 50¢
50¢ + 20¢ + 20¢ + 10¢
20¢ + 20 ¢ + 20¢ + 20¢ + 20¢
etc.
Recursion
1. Express (divide) the problem into smaller
similar problem(s)
2. Solve the problem for a simple (base) case
Understand the problem
What are the inputs?
- The amount: a (in cents).
- Types-of-coins: {𝑑1 , 𝑑2 , … , 𝑑𝑛 }
e.g. only 50¢ and 20¢

What is the output?


- The number of ways
Recursive Idea
Given a particular set of coins
𝑘1 , 𝑘2 , … , 𝑘𝑛
the change for an amount 𝑎 can be divided into
two disjoint sets:

1. Those that have least one 𝑘1 coin


2. Those that do not use any 𝑘1 coins
Recursive Idea

• 50 + 50
• 50 + 20 + 20 + 10 • 20 + 20 + 20 + 20 + 20
• 20 + 20 + 20 + 20 + 10
• 50 + 20 + 10 + 10 + 10
+10 • ….
• …

Number of ways with using at Number of ways without


least one 50 cents coin using any 50 cents coin
Divide and Conquer

The amount changes


$1 The amount doesn’t change
{50, 20, 10, 5 ,1}
The kind of coins don’t The kind of coins change

50¢ + 50¢ $1
{50, 20, 10, 5 ,1} {20, 10, 5 ,1}
In general

𝑎
{𝑑1, 𝑑2, … , 𝑑𝑘 }

𝑑1 + 𝑎 − 𝑑1 𝑎
{𝑑1, 𝑑2, … , 𝑑𝑘 } {𝑑2, … , 𝑑𝑘 }
Base Case
If amount is zero
- There is exactly 1 way!

If amount is less than zero or if there are no


coins available
- There is no way to make change.
Recursive Step
Let’s denote cc(amt, coins) counts the number of
ways to get amt using coins.
cc(amt, coins) =
cc(amt – denomination(coins), coins) +
cc(amt, coins – 1)

COINS DENOMINATION
5 50
4 20 abstraction
3 10
2 5
1 1
Python function
def cc(amount, kinds_of_coins):
if amount == 0:
return 1
elif (amount < 0) or (kinds_of_coins == 0):
return 0 Using 1 coin for
first kind
else:
return cc(amount – first_denomination(kinds_of_coins),
kinds_of_coins) +
cc(amount, kinds_of_coins-1)
Without using first
def first_denomination(kinds_of_coins): kind of coin
… <left as an exercise>

def count_change(amount)
return cc(amount,5)
Iteration
Counting change is easily formulated via recursive
process.

Can you write an iterative process to count change?

Can, but not


easy!

https://pollev.com/ashishdandekar
Summary
• Recursion
- Solve the problem for a simple (base) case
- Express (divide) a problem into one or more
smaller similar problems

• Iteration:
- while and for loops
Summary
• All problems that can be solved using recursion
can also be solved using iteration.

• All problems that can be solved using iteration


can also be solved using recursion.

• At times, one approach is easier than the other,


and perhaps more efficient too!
More Examples
Greatest Common Divisor

The GCD of two numbers 𝑎 and 𝑏, is the


largest positive integer that divides both 𝑎
and 𝑏 without remainder.
Greatest Common Divisor

Naïve Solution.
1. Set GCD to 1.
2. Start with 1.
3. Check for every number if it divides and b. If it
does, set it as GCD.
4. Continue until you reach a or b.
Greatest Common Divisor
Euclid’s Algorithm.
32 = 7 ∗ 4 + 4
Given two numbers a and b, where
𝑎 = 𝑏𝑄 + 𝑟 (the remainder of the division).

Then we have,
𝐺𝐶𝐷 𝑎, 𝑏 = 𝐺𝐶𝐷 𝑏, 𝑟 , ∀𝑎, 𝑏 > 0
𝐺𝐶𝐷(𝑎, 0) = 𝑎
Greatest Common Divisor
def gcd(a, b): 𝐺𝐶𝐷 𝑎, 𝑏 = 𝐺𝐶𝐷 𝑏, 𝑟 , ∀ 𝑎, 𝑏
if (b == 0): 𝐺𝐶𝐷(𝑎, 0) = 𝑎
return a
else:
return gcd(b, a % b)

GCD(206,40) = GCD(40,6)
= GCD(6,4)
= GCD(4,2)
= GCD(2,0)
= 2
Another Example
Exponentiation – another angle!
power(a, 13)
1 𝑒=0
𝑒
𝑒
𝑏 =൞ (𝑏 2 )2 𝑒 is even = a * power(a, 12)
𝑏 ⋅ 𝑏 𝑒−1 𝑒 is odd = a * power(b, 6) b = a*a
= a * power(c, 3) c = b*b
= a * c * power(c, 2)
= a * c * power(d, 1) d = c*c
= a * c * d * power(d, 0)

Actual number of operations!


Fast Exponentiation
def fast_expt(b, e):
if e == 0:
return 1
elif e % 2 == 0:
return fast_expt(b*b, e//2)
else:
return b * fast_expt(b, e-1)

• Time requirement? O(log 𝑒)


• Space requirement? O(log 𝑒)
Can we do this iteratively?
Something to think about….
• Can you write a recursive function
sum_of_digits that will return the sum of digits of
an arbitrary positive integer?

• How about a recursive function


product_of_digits that will return the product of
the digits?
Notice a pattern?
How would you write a function that
computed the sum of square roots of the
digits of a number?

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy