2020 Day6 Functions Recursion Python
2020 Day6 Functions Recursion Python
http://www.isical.ac.in/~dfslab/2020/index.html
def function1 (x) : def function3 (l) :
x = 10 l = [ 10 ]
return return
Call by value
argument expressions evaluated
values copied into local storage area of called function
changes made to parameters in called function not reflected in caller
Call by reference
reference to argument (its address) copied into local storage area of
called function
changes made to argument variables in callee are reflected in caller
Call by name
Call by reference
Immutable arguments (integers, strings, tuples): passed by value or
reference (doesn’t matter)
Mutable arguments: passed by reference
in place changes reflected in caller
if the name is reassigned, it points to a different object
Call by reference
Immutable arguments (integers, strings, tuples): passed by value or
reference (doesn’t matter)
Mutable arguments: passed by reference
in place changes reflected in caller
if the name is reassigned, it points to a different object
>>> x = 10
>>> id(x)
10914784
x x now points to a
x = x + 1 different object
>>> y = 10 x = a
>>> id(y) vs.
10914784 x
>>> y = y+1 x.inplace_operation()
>>> id(y) x = b
10914816
DFS Lab (ISI) Functions and Recursion in Python 4 / 20
Recursion
The task should be decomposable into sub-tasks that are smaller, but
otherwise identical in structure to the original problem.
The simplest sub-tasks (called the base case) should be (easily)
solvable directly, i.e., without decomposing it into similar
sub-problems.
def factorial(n) :
# Not recommended!
if n < 0 : return -1 def factorial(n) : # Recursive implementation
Problem statement
Consider a 2-D matrix of size 2m × 2m . The entries of the matrix are, in
row-major order, 1, 2, 3, . . . , 22m . Print the entries of the matrix in Z-curve
order (as shown in the picture below).
(N − 1, N − 1)
# Base case
if top_left_row == bottom_right_row and \
top_left_column == bottom_right_column :
print("%d" % matrix[top_left_row][top_left_column], end=" ")
return
TLC
TLR
BRR
BRC
# Base case
if top_left_row == bottom_right_row and \
top_left_column == bottom_right_column :
print("%d" % matrix[top_left_row][top_left_column], end=" ")
return
TLC BRC
TLR TLR
BRR BRR
TLC BRC
# Base case
if top_left_row == bottom_right_row and \
top_left_column == bottom_right_column :
print("%d" % matrix[top_left_row][top_left_column], end=" ")
return
BRR BRR
TLC BRC
# Base case
if top_left_row == bottom_right_row and \
top_left_column == bottom_right_column :
print("%d" % matrix[top_left_row][top_left_column], end=" ")
return
BRR BRR
TLC (TLC + BRC)//2 (TLC + BRC)//2 + 1 BRC
# Base case
if top_left_row == bottom_right_row and \
top_left_column == bottom_right_column :
print("%d" % matrix[top_left_row][top_left_column], end=" ")
return
BRR BRR
TLC (TLC + BRC)//2 (TLC + BRC)//2 + 1 BRC
# upper-left sub-square
z_curve(matrix,
top_left_row,
top_left_column,
(top_left_row + bottom_right_row)//2,
(top_left_column + bottom_right_column)//2)
# upper-right sub-square
z_curve(matrix,
top_left_row,
(top_left_column + bottom_right_column)//2 + 1,
(top_left_row + bottom_right_row)//2,
bottom_right_column)
# lower-left sub-square
z_curve(matrix,
(top_left_row + bottom_right_row)//2 + 1,
top_left_column,
bottom_right_row,
(top_left_column + bottom_right_column)//2)
DFS Lab (ISI) Functions and Recursion in Python 10 / 20
Z curve: code
# lower-right sub-square
z_curve(matrix,
(top_left_row + bottom_right_row)//2 + 1,
(top_left_column + bottom_right_column)//2 + 1,
bottom_right_row,
bottom_right_column)
return
N = 2**2
i = 1; j = 0
A = [ [ x for x in range(j*N+i, j*N+i+N) ] for j in range(N) ]
z_curve(A,0,0,N-1,N-1); print()
Algorithm
To generate all permutations of 1, 2, 3, . . . , n, do the following:
1. Generate all permutations of 2, 3, . . . , n.
2. For each of the permutations generated above
(1) add 1 in the beginning;
(2) add 1 in the 2nd position;
...
(n) add 1 at the end.
def permute(A) :
n = len(A)
if n < 2: return [ A ]
return permlist
6. In chess, a knight can move to a cell that is horizontally 2 cells and vertically 1 cell away, or
vertically 2 cells and horizontally 1 cell away (see Fig. 6). Thus, eight moves are possible for a
knight in general.
Given an m × n chess-like board, and a knight at position (i, j) (where 0 ≤ i < m and
0 ≤ j < n), compute the probability that the knight remains on the board after a given number
(say k) of steps, assuming that, at each step, all eight moves are equally likely. Note that, once
the knight moves off the board, it can never return to the board.
Input Format
mnijk
Output Format
The probability value rounded up to 6 decimal places.
Sample Input 0
12011
Sample Output 0
0.000000
Sample Input 1
88331
Sample Output 1
1.000000
Sample Input 2
66001
Sample Output 2
0.250000
Sample Input 3
44002
Sample Output 3
0.125000
Explanation for the above
0 1 2 3
The knight starts at the top-left corner
(0,0). After 1 move, it may either move
0 0/2/2 2
off the board (permanently), or go to the
squares marked 1 (in red / blue). After
another move from the square marked
1 1 2 with a red (respectively, blue) 1, it lands
on one of the squares marked with a red
(respectively, blue) 2, or moves off the
2 2 1 board. The knight stays on the board for
8 distinct sequences of moves (of 2
steps each). The total number of such
3 2 2/2 moves of 2 steps each is 8 × 8 = 64.
7. Write a program that takes a positive integer n ≤ 5, and a non-negative integer k ≤ 100 as
command-line arguments, and computes the total number of cells reachable from any starting
cell within an infinite, n-dimensional grid in k steps or less. See the examples below. You are
only permitted to travel in a direction that is parallel to one of the grid lines; diagonal movement
is not permitted.
NOTE: If you are interested, you may compute a closed-form expression for the required
number, but DO NOT use the closed-form expression to compute the answer to this problem.
Starting Cell
2 1 2
2 1 0 1 2
2 1 2