cs61a home work 3

494 阅读1分钟

cs61a home work 3

Q1: Neighbor Digits
Implement the function neighbor_digits. neighbor_digits takes in a positive integer num and an optional argument prev_digit. neighbor_digits outputs the number of digits in num that have the same digit to its right or left.

def neighbor_digits(num, prev_digit=-1):
    """
    Returns the number of digits in num that have the same digit to its right
    or left.
    >>> neighbor_digits(111)
    3
    >>> neighbor_digits(123)
    0
    >>> neighbor_digits(112)
    2
    >>> neighbor_digits(1122)
    4
    """
    if num < 10:
        return num == prev_digit
    last = num % 10
    rest = num // 10
    return int(prev_digit == last or rest % 10 == last) + neighbor_digits(num // 10, last)
    
    '''
    整个代码写得很精妙
    把代码数字分成两部分:last和rest。
    
    prev_digit这个参数是前一个数字,相当于last,num % 10取得最后一位数字,num // 10取得rest
    
    所以整个思路是,当前数字取last和rest,然后第一次比较prev_digit是无效的,所以需要用or条件,也因为是or条件,所以只能一个True
    
    如此反复
    
    此题还涉及到逻辑型的一些转换和运算
    
    其中 return int(prev_digit == last or rest % 10 == last) 把逻辑型转换为数值型并加上数值或逻辑型,因为最后一个base case是
    
    return num == prev_digit,返回值只能是True or False
 
    所以就涉及数值型和逻辑型的加法运算
    
    以下是逻辑型转换和运算的例子:
    
>>> int(1 == 1 or 11 % 10 == last)
1
>>> 1 == 1
True
>>> 1 + True
2
>>> 1 + False
1
    
    
    
def has_subseq(n, seq):
    """
    Complete has_subseq, a function which takes in a number n and a "sequence"
    of digits seq and returns whether n contains seq as a subsequence, which
    does not have to be consecutive.

    >>> has_subseq(123, 12)
    True
    >>> has_subseq(141, 11)
    True
    >>> has_subseq(144, 12)
    False
    >>> has_subseq(144, 1441)
    False
    >>> has_subseq(1343412, 134)
    True
    """
    if seq < 10 and (seq % 10 == n % 10):
        return True

    if seq < 10 and n < 10 and (seq % 10 != n % 10):
        return False

    if n < 10 and (n % 10 != seq % 10):
        return False

    if n % 10 == seq % 10:
        return has_subseq(n // 10,seq // 10)
    else:
        return has_subseq(n // 10,seq)


自已写的答案,此题注意判断n和seq的结束条件,刚开始没判断n的结束条件,测试样例4过不了

===========官网答案====================
def has_subseq(n, seq):
    """
    Complete has_subseq, a function which takes in a number n and a "sequence"
    of digits seq and returns whether n contains seq as a subsequence, which
    does not have to be consecutive.

    >>> has_subseq(123, 12)
    True
    >>> has_subseq(141, 11)
    True
    >>> has_subseq(144, 12)
    False
    >>> has_subseq(144, 1441)
    False
    >>> has_subseq(1343412, 134)
    True
    """
    if n == seq:
        return True
    if n < seq:
        return False
    without = has_subseq(n // 10, seq)
    if seq % 10 == n % 10:
        return has_subseq(n // 10, seq // 10) or without
    return without
    

注:结束条件写得比我精巧多了


HW_SOURCE_FILE = __file__


def num_eights(pos):
    """Returns the number of times 8 appears as a digit of pos.

    >>> num_eights(3)
    0
    >>> num_eights(8)
    1
    >>> num_eights(88888888)
    8
    >>> num_eights(2638)
    1
    >>> num_eights(86380)
    2
    >>> num_eights(12345)
    0
    >>> from construct_check import check
    >>> # ban all assignment statements
    >>> check(HW_SOURCE_FILE, 'num_eights',
    ...       ['Assign', 'AnnAssign', 'AugAssign', 'NamedExpr'])
    True
    """
    if pos < 10 and pos == 8:
        return 1

    if pos < 10 and pos != 8:
        return 0

    if pos % 10 == 8:
        return 1 + num_eights(pos // 10)
    else:
        return num_eights(pos // 10)
        
 注解:这道题比较简单



def pingpong(n):
    """Return the nth element of the ping-pong sequence.

    >>> pingpong(8)
    8
    >>> pingpong(10)
    6
    >>> pingpong(15)
    1
    >>> pingpong(21)
    -1
    >>> pingpong(22)
    -2
    >>> pingpong(30)
    -2
    >>> pingpong(68)
    0
    >>> pingpong(69)
    -1
    >>> pingpong(80)
    0
    >>> pingpong(81)
    1
    >>> pingpong(82)
    0
    >>> pingpong(100)
    -6
    >>> from construct_check import check
    >>> # ban assignment statements
    >>> check(HW_SOURCE_FILE, 'pingpong',
    ...       ['Assign', 'AnnAssign', 'AugAssign', 'NamedExpr'])
    True
    """
    def helper(result,i,step):
        if i == n:
            return result  # base case 结束条件
        elif i % 8 == 0 or num_eights(i)>0:  # or条件我觉得其实可以不用 
            return helper(result-step,i+1,-step) # -step其实是开始转向传递给下一层,同时本层result-step已减,下一层
        else:                                    # 进入 else的helper的step其实就是-1
            return helper(result+step,i+1,step)
    return helper(1,1,1)  # 初始条件

# 官网答案