Exercise 1
what is yield
in python?
The yield keyword in Python is used to create generator functions. A generator function is a special kind of function that returns a generator iterator, which can be used to iterate over a sequence of values. Unlike a regular function that returns a single value using the return statement, a generator function can yield multiple values, one at a time, pausing its state between each one.
How it works?
When a generator function is called, it doesn’t execute its code immediately. Instead, it returns a generator object that can be iterated over. Each time you request the next item from the generator (using next() or a loop), the generator function resumes execution from where it last left off, runs until it hits a yield statement, and yields the value to the caller.
Problem Description
First, we need to understand the requirements of the problem:
Input: A list of integers L, such as [n1, n2, n3, …]. Output:
- Output n1 lines of rank 1 X, which means X without indentation.
- Between each pair of rank 1 X, output n2 lines of rank 2 X, which are indented with one tab (\t).
- Between each pair of rank 2 X, output n3 lines of rank 3 X, which are indented with two tabs.
- Continue this pattern until all elements in the list L have been processed.
My solution
1 | def f1(): |
Standard solution
1 | def f1(): |
Exercise 2
Problem Description
1 | Line: [1, 3, 3, 1] |
My solution
1 | def f2(): |
Standard solution
1 | def f2(): |
Exercise 3
Problem Description
First, we need to understand the requirements of the problem:
Input: A list of integers L, such as [n1, n2, n3, …]. Output:
- Output n1 lines of rank 1 X, which means X without indentation.
- Between each pair of rank 1 X, output n2 lines of rank 2 X, which are indented with one tab (\t).
- Between each pair of rank 2 X, output n3 lines of rank 3 X, which are indented with two tabs.
- Continue this pattern until all elements in the list L have been processed.
My solution
1 | def f3(L): |
We need to write a recursive function to handle this nested structure. Here is the implementation idea:
Define a helper function helper(L, rank)
, where:
L
is the list currently being processed.rank
is the current level (indentation level).
In the helper
function:
- If the list is empty, return directly.
- Get the number of lines to output at the current level,
n = L[0]
. - Use a loop to output
n
lines of the current level’s X, with each line having the corresponding number of tab characters (\t
) based on therank
. - After each output, if it is not the last element and it is not the last line, recursively call
helper
to handle the next level ofX
lines.
Standard solution
1 |
|
Exercise 4
Problem Description
Objective: Given a list L
of integers, we need to:
- Break it down into sublists of equal length, where the length is maximal.
- This process is recursive: each sublist is further broken down in the same manner.
- The original list should be preserved (i.e., not modified).
Key Points:
- We aim to split the list into the largest possible sublists of equal length (greater than 1) that evenly divide the length of the list.
- The recursion continues until a sublist cannot be broken down further (i.e., its length cannot be divided into equal parts greater than 1).
My solution
1 | from math import sqrt |
Standard solution
1 |
|
Exercise 5
Problem Description
Objective: Given a special list L
(a list whose elements are integers or other special lists), we need to return a dictionary where:
Keys are tuples of indices (i_1, i_2, ..., i_n)
.
Values are integers e
.
The keys represent the path of indices to reach an integer e
within the nested list structure.
Interpretation:
- If the key is
(i_1,)
, thenL[i_1]
is an integere
. - If the key is
(i_1, i_2)
, thenL[i_1][i_2]
is an integere
. - If the key is
(i_1, i_2, i_3)
, thenL[i_1][i_2][i_3]
is an integere
. - And so on.
Constraints:
We need to handle any depth of nesting.
Use isinstance()
to check if an element is an integer or a list.
The original list should not be modified.
My solution
1 | def f5(L): |
Standard solution
1 | def f5(L): |
Difference between my solution and the standard solution
My Solution
- Uses a Helper Function (helper): Your solution defines an inner function helper(sublist, path) to handle the recursion.
- Explicit Path Passing: The path variable, representing the current position in the nested list, is explicitly passed and updated at each recursive call.
- State Encapsulation: By using a nested function, the state (path and result) is encapsulated within the f5 function’s scope.
Standard Solution
- Direct Recursion: The standard solution directly calls f5(L[i]) recursively without using a helper function.
- Implicit Path Construction: It constructs the path by combining the current index i with the indices from the recursive call (s) using tuple unpacking.
- Dictionary Merging: After each recursive call, it merges the returned dictionary E into the current dictionary D.
Exercise 6
Problem Description
The given problem is not strictly about the Fibonacci sequence, but it generalizes similar principles to a broader set of recursive relationships. In the problem, you’re asked to compute the n-th term of a series, where the series is defined by some initial terms (first_terms) and a set of recurrence factors (factors). The Fibonacci sequence is a special case of such a recurrence relation, where each term is the sum of the two preceding terms.
My solution(Wrong)
1 |
|
Standard solution
1 | def f6(first_terms, factors, n): |