# [2021-Fall] Lab05 of CS61A of UCB

## Lists

### Q1: Factors List

Write factors_list, which takes a number n and returns a list of its factors in ascending order.

def factors_list(n):
"""Return a list containing all the numbers that divide n evenly, except
for the number itself. Make sure the list is in ascending order.

>>> factors_list(6)
[1, 2, 3]
>>> factors_list(8)
[1, 2, 4]
>>> factors_list(28)
[1, 2, 4, 7, 14]
"""
all_factors = []
# the biggest number which can divide n evenly will be n // 2
for i in range(1, n // 2 + 1):
if n % i == 0:
all_factors.append(i)
return all_factors


### Q2: Flatten

Write a function flatten that takes a list and "flattens" it. The list could be a deep list, meaning that there could be a multiple layers of nesting within the list.

For example, one use case of flatten could be the following:

>>> lst = [1, [, 3], 4, [5, 6]]
>>> flatten(lst)
[1, 2, 3, 4, 5, 6]


Make sure your solution does not mutate the input list.

1. 什么是 base case ? 如果是空的 list 就返回 []
2. 怎么递归分解为更简单的子问题 ? 也就是我们要如何缩小问题的规模, 我们可以每次尝试处理嵌套 list 的第一个位置的元素, 根据它们是不是 list 可以分解出两种情况.

def flatten(s):
"""Returns a flattened version of list s.

>>> flatten([1, 2, 3])     # normal list
[1, 2, 3]
>>> x = [1, [2, 3], 4]     # deep list
>>> flatten(x)
[1, 2, 3, 4]
>>> x # Ensure x is not mutated
[1, [2, 3], 4]
>>> x = [[1, [1, 1]], 1, [1, 1]] # deep list
>>> flatten(x)
[1, 1, 1, 1, 1, 1]
>>> x
[[1, [1, 1]], 1, [1, 1]]
"""
if s == []:
return []
elif type(s) == list:
return flatten(s) + flatten(s[1:])
else:
return s[:1] + flatten(s[1:])


## Data Abstraction

### Q3: Distance

We will now implement the function distance, which computes the distance between two city objects. Recall that the distance between two coordinate pairs (x1, y1) and (x2, y2) can be found by calculating the sqrt of (x1 - x2)**2 + (y1 - y2)**2. We have already imported sqrt for your convenience. Use the latitude and longitude of a city as its coordinates; you'll need to use the selectors to access this info!

def distance(city_a, city_b):
"""
>>> city_a = make_city('city_a', 0, 1)
>>> city_b = make_city('city_b', 0, 2)
>>> distance(city_a, city_b)
1.0
>>> city_c = make_city('city_c', 6.5, 12)
>>> city_d = make_city('city_d', 2.5, 15)
>>> distance(city_c, city_d)
5.0
"""
x = (get_lat(city_a) - get_lat(city_b)) ** 2
y = (get_lon(city_a) - get_lon(city_b)) ** 2
return sqrt(x + y)


### Q4: Closer city

Next, implement closer_city, a function that takes a latitude, longitude, and two cities, and returns the name of the city that is relatively closer to the provided latitude and longitude.

You may only use the selectors and constructors introduced above and the distance function you just defined for this question.

Hint: How can you use your distance function to find the distance between the given location and each of the given cities?

def closer_city(lat, lon, city_a, city_b):
"""
Returns the name of either city_a or city_b, whichever is closest to
coordinate (lat, lon). If the two cities are the same distance away
from the coordinate, consider city_b to be the closer city.

>>> berkeley = make_city('Berkeley', 37.87, 112.26)
>>> stanford = make_city('Stanford', 34.05, 118.25)
>>> closer_city(38.33, 121.44, berkeley, stanford)
'Stanford'
>>> bucharest = make_city('Bucharest', 44.43, 26.10)
>>> vienna = make_city('Vienna', 48.20, 16.37)
>>> closer_city(41.29, 174.78, bucharest, vienna)
'Bucharest'
"""
tmp = make_city('tmp', lat, lon)
if distance(tmp, city_a) < distance(tmp, city_b):
return get_name(city_a)
else:
return get_name(city_b)


## Trees

### Q6: Finding Berries!

The squirrels on campus need your help! There are a lot of trees on campus and the squirrels would like to know which ones contain berries. Define the function berry_finder, which takes in a tree and returns True if the tree contains a node with the value 'berry' and False otherwise.

Hint: To iterate through each of the branches of a particular tree, you can consider using a for loop to get each branch.

1. 什么是 base case ? 显然为叶子结点的时候是 base case, 这个时候我们看它的 label 是不是
2. 怎么分解为更简单的子问题 ? 容易想到, 我们只要有任何一个分支的某个节点存在 berry 即可, 或者说我们当前分支的 label 为 berry.
def berry_finder(t):
"""Returns True if t contains a node with the value 'berry' and
False otherwise.

>>> scrat = tree('berry')
>>> berry_finder(scrat)
True
>>> sproul = tree('roots', [tree('branch1', [tree('leaf'), tree('berry')]), tree('branch2')])
>>> berry_finder(sproul)
True
>>> numbers = tree(1, [tree(2), tree(3, [tree(4), tree(5)]), tree(6, [tree(7)])])
>>> berry_finder(numbers)
False
>>> t = tree(1, [tree('berry',[tree('not berry')])])
>>> berry_finder(t)
True
"""
if is_leaf(t):
return label(t) == 'berry'
return any([berry_finder(b) for b in branches(t)]) or label(t) == 'berry'


### Q7: Sprout leaves

Define a function sprout_leaves that takes in a tree, t, and a list of leaves, leaves. It produces a new tree that is identical to t, but where each old leaf node has new branches, one for each leaf in leaves.

For example, say we have the tree t = tree(1, [tree(2), tree(3, [tree(4)])]):

 1
/ \
2   3
|
4


If we call sprout_leaves(t, [5, 6]), the result is the following tree:

      1
/   \
2     3
/ \    |
5   6   4
/ \
5   6


def sprout_leaves(t, leaves):    """Sprout new leaves containing the data in leaves at each leaf in    the original tree t and return the resulting tree.    >>> t1 = tree(1, [tree(2), tree(3)])    >>> print_tree(t1)    1      2      3    >>> new1 = sprout_leaves(t1, [4, 5])    >>> print_tree(new1)    1      2        4        5      3        4        5    >>> t2 = tree(1, [tree(2, [tree(3)])])    >>> print_tree(t2)    1      2        3    >>> new2 = sprout_leaves(t2, [6, 1, 2])    >>> print_tree(new2)    1      2        3          6          1          2    """    if is_leaf(t):        return tree(label(t), [tree(leaf) for leaf in leaves])    return tree(label(t), [sprout_leaves(b, leaves) for b in branches(t)])

posted @ 2022-02-19 17:11  MartinLwx  阅读(1140)  评论(0编辑  收藏  举报