2021 fall cs61a lab14

网址 https://inst.eecs.berkeley.edu/~cs61a/fa21/lab/lab14/

problem1:

从上到下,每一次裁剪掉数值大的那个树枝
def prune_min(t):
"""Prune the tree mutatively.

        >>> t1 = Tree(6)
        >>> prune_min(t1)
        >>> t1
        Tree(6)
        >>> t2 = Tree(6, [Tree(3), Tree(4)])
        >>> prune_min(t2)
        >>> t2
        Tree(6, [Tree(3)])
        >>> t3 = Tree(6, [Tree(3, [Tree(1), Tree(2)]), Tree(5, [Tree(3), Tree(4)])])
        >>> prune_min(t3)
        >>> t3
        Tree(6, [Tree(3, [Tree(1)])])
        """
        "*** YOUR CODE HERE ***"
        if t.is_leaf():
            return 
        # go deeper if it has 1 child
        if len(t.branches) == 1:
            prune_min(t.branches[0])

        left, right = t.branches[0], t.branches[1]
        if left.label < right.label:
            del t.branches[1]           # prune right branch
            prune_min(left)
        else:
            del t.branches[0]           # prune left branch
            prune_min(right)

problem2:

这个难在要分为两个部分,不能用之前常用的递归,这里用了let先把后面的实现,再在前一部分加一个数字

    (define (split-at lst n)
     (cond ((= n 0) (cons nil lst))
     ((null? lst) (cons lst nil))
     (else (let ((rec (split-at (cdr lst) (- n 1))))
     (cons (cons (car lst) (car rec)) (cdr rec)))))
    )

problem3:

    (define (compose-all funcs ) 
        (lambda (x)
            (if (null? funcs)
            x
            ((compose-all (cdr funcs)) ((car funcs) x))))
    )

problem4:

这个主要是理解题目意思,先是一个三到五位的数字,然后是街道名称,一个可以以[NEWS]单个字母开头也可以不用,然后在是一个多字母的名称,最后是一个2到5个字母的缩写,街道名称全部要大写开头
def address_oneline(text):
"""
Finds and returns expressions in text that represent the first line
of a US mailing address.

        >>> address_oneline("110 Sproul Hall, Berkeley, CA 94720")
        ['110 Sproul Hall']
        >>> address_oneline("What's at 39177 Farwell Dr? Is there a 39177 Nearwell Dr?")
        ['39177 Farwell Dr', '39177 Nearwell Dr']
        >>> address_oneline("I just landed at 780 N McDonnell Rd, and I need to get to 1880-ish University Avenue. Help!")
        ['780 N McDonnell Rd']
        >>> address_oneline("123 Le Roy Ave")
        ['123 Le Roy Ave']
        >>> address_oneline("110 Unabbreviated Boulevard")
        []
        >>> address_oneline("790 lowercase St")
        []
        """
        block_number = r'\d{3,5}'
        cardinal_dir = r'(?:[NSWE] )?'  # whitespace is important!
        street = r'(?:[A-Z][A-Za-z]+ )+'
        type_abbr = r'[A-Z][a-z]{1,4}\b'
        street_name = f"{cardinal_dir}{street}{type_abbr}"
        return re.findall(f"{block_number} {street_name}", text)

problem5 and 6:

    create table pizzas as
      select "Pizzahhh" as name, 12 as open, 15 as close union
      select "La Val's"        , 11        , 22          union
      select "Sliver"          , 11        , 20          union
      select "Cheeseboard"     , 16        , 23          union
      select "Emilia's"        , 13        , 18;

    create table meals as
      select "breakfast" as meal, 11 as time union
      select "lunch"            , 13         union
      select "dinner"           , 19         union
      select "snack"            , 22;


    -- Pizza places that open before 1pm in alphabetical order
    create table opening as
      SELECT name
      FROM pizzas
      WHERE open < 13 ORDER BY name DESC  ;


    -- Two meals at the same place
    create table double as
      SELECT a.meal, b.meal, name
      FROM meals as a, meals as b, pizzas
      where open <= a.time and a.time <= close and
            open <= b.time and b.time <= close and
            b.time > a.time + 6;

peoblem 7:

    class Player:
        """
        >>> random = make_test_random()
        >>> p1 = Player('Hill')
        >>> p2 = Player('Don')
        >>> p1.popularity
        100
        >>> p1.debate(p2)  # random() should return 0.0
        >>> p1.popularity
        150
        >>> p2.popularity
        100
        >>> p2.votes
        0
        >>> p2.speech(p1)
        >>> p2.votes
        10
        >>> p2.popularity
        110
        >>> p1.popularity
        135

        """

        def __init__(self, name):
            self.name = name
            self.votes = 0
            self.popularity = 100

        def debate(self, other):
            r = random()
            if r < max(0.1, (self.popularity / (self.popularity + other.popularity))):
                self.popularity += 50
            else:
                self.popularity -= 50
                if self.popularity < 0:
                    self.popularity = 0
        def speech(self, other):
            self.votes += self.popularity // 10
            self.popularity += self.popularity // 10
            other.popularity -= other.popularity // 10
            if other.popularity < 0:
                other.popularity = 0
        def choose(self, other):
            return self.speech

problem8:

    class Game:
        """
        >>> p1, p2 = Player('Hill'), Player('Don')
        >>> g = Game(p1, p2)
        >>> winner = g.play()
        >>> p1 is winner
        True

        """

        def __init__(self, player1, player2):
            self.p1 = player1
            self.p2 = player2
            self.turn = 0

        def play(self):
            while not self.game_over:
                if self.turn % 2 == 0 :
                    cur, other = self.p1, self.p2
                else:
                    cur, other = self.p2, self.p1
                cur.choose(other)(other)
                self.turn += 1
            return self.winner

        @property
        def game_over(self):
            return max(self.p1.votes, self.p2.votes) >= 50 or self.turn >= 10

        @property
        def winner(self):
            if self.p1.votes == self.p2.votes:
                return None
            if self.p1.votes > self.p2.votes :
                return self.p1
            else:
                return self.p2

problem9:

    class AggressivePlayer(Player):
        """
        >>> random = make_test_random()
        >>> p1, p2 = AggressivePlayer('Don'), Player('Hill')
        >>> g = Game(p1, p2)
        >>> winner = g.play()
        >>> p1 is winner
        True

        """

        def choose(self, other):
            if self.popularity <= other.popularity:
                return self.debate
            else:
                return self.speech


    class CautiousPlayer(Player):
        """
        >>> random = make_test_random()
        >>> p1, p2 = CautiousPlayer('Hill'), AggressivePlayer('Don')
        >>> p1.popularity = 0
        >>> p1.choose(p2) == p1.debate
        True
        >>> p1.popularity = 1
        >>> p1.choose(p2) == p1.debate
        False

        """

        def choose(self, other):
            if self.popularity == 0:
                return self.debate
            else:
                return self.speech

problem10:

先是给出新的label,然后把不一样长的列表完善到一样长,再建立新的树。

    def add_trees(t1, t2):
        """
        >>> numbers = Tree(1,
        ...                [Tree(2,
        ...                      [Tree(3),
        ...                       Tree(4)]),
        ...                 Tree(5,
        ...                      [Tree(6,
        ...                            [Tree(7)]),
        ...                       Tree(8)])])
        >>> print(add_trees(numbers, numbers))
        2
          4
            6
            8
          10
            12
              14
            16
        >>> print(add_trees(Tree(2), Tree(3, [Tree(4), Tree(5)])))
        5
          4
          5
        >>> print(add_trees(Tree(2, [Tree(3)]), Tree(2, [Tree(3), Tree(4)])))
        4
          6
          4
        >>> print(add_trees(Tree(2, [Tree(3, [Tree(4), Tree(5)])]), \
        Tree(2, [Tree(3, [Tree(4)]), Tree(5)])))
        4
          6
            8
            5
          5
        """
        "*** YOUR CODE HERE ***"
        if not t1:
            return t2
        if not t2:
            return t1
        new_label = t1.label + t2.label
        t1_branches, t2_branches = list(t1.branches), list(t2.branches)
        length_t1, length_t2 = len(t1_branches), len(t2_branches)
        if length_t1 < length_t2:
            t1_branches += [None for _ in range(length_t1, length_t2)]
        elif length_t1 > length_t2:
            t2_branches += [None for _ in range(length_t2, length_t1)]
        return Tree(new_label,[add_trees(branch1, branch2) for branch1, branch2 in zip(t1_branches, t2_branches)])

problem 11 and 12:

    def foldl(link, fn, z):
        """ Left fold
        >>> lst = Link(3, Link(2, Link(1)))
        >>> foldl(lst, sub, 0) # (((0 - 3) - 2) - 1)
        -6
        >>> foldl(lst, add, 0) # (((0 + 3) + 2) + 1)
        6
        >>> foldl(lst, mul, 1) # (((1 * 3) * 2) * 1)
        6
        """
        if link is Link.empty:
            return z
        z = fn(z, link.first)
        link = link.rest
        return foldl(link, fn, z)


    def foldr(link, fn, z):
        """ Right fold
        >>> lst = Link(3, Link(2, Link(1)))
        >>> foldr(lst, sub, 0) # (3 - (2 - (1 - 0)))
        2
        >>> foldr(lst, add, 0) # (3 + (2 + (1 + 0)))
        6
        >>> foldr(lst, mul, 1) # (3 * (2 * (1 * 1)))
        6
        """
        if link is Link.empty:
            return z
        z = fn(link.first, foldr(link.rest, fn, z))
        return z

problem 13:

    def match_url(text):
        """
        >>> match_url("https://cs61a.org/resources/#regular-expressions")
        True
        >>> match_url("https://pythontutor.com/composingprograms.html")
        True
        >>> match_url("https://pythontutor.com/should/not.match.this")
        False
        >>> match_url("https://link.com/nor.this/")
        False
        >>> match_url("http://insecure.net")
        True
        >>> match_url("htp://domain.org")
        False
        """
        scheme = r'https?:\/\/'
        domain = r'\w[\w.]+\w'
        path = r'\/(?:[\w\/]+)(?:\.\w+)?'
        anchor = r'#[\w-]+'
        return bool(re.match(rf"^(?:{scheme})?{domain}(?:{path})?(?:{anchor})?$", text))

problem14:

posted @ 2022-05-03 15:55  天然气之子  阅读(257)  评论(0编辑  收藏  举报