class Link: empty = () def __init__(self, first, rest=empty): assert rest is Link.empty or isinstance(rest, Link) self.first = first self.rest = rest def __contains__(self, value): "*** YOUR CODE HERE ***" class ScaleIterator: """An iterator the scales elements of the iterable s by a number k. >>> s = ScaleIterator([1, 5, 2], 5) >>> list(s) [5, 25, 10] >>> m = ScaleIterator(naturals(), 2) >>> [next(m) for _ in range(5)] [2, 4, 6, 8, 10] """ def __init__(self, s, k): "*** YOUR CODE HERE ***" def __iter__(self): return self def __next__(self): "*** YOUR CODE HERE ***" def scale(s, k): """Yield elements of the iterable s scaled by a number k. >>> s = scale([1, 5, 2], 5) >>> type(s) >>> list(s) [5, 25, 10] >>> m = scale(naturals(), 2) >>> [next(m) for _ in range(5)] [2, 4, 6, 8, 10] """ "*** YOUR CODE HERE ***" def merge(s0, s1): """Yield the elements of strictly increasing iterables s0 and s1, removing repeats. Assume that s0 and s1 have no repeats. You can also assume that s0 and s1 represent infinite sequences. >>> twos = scale(naturals(), 2) >>> threes = scale(naturals(), 3) >>> m = merge(twos, threes) >>> type(m) >>> [next(m) for _ in range(10)] [2, 3, 4, 6, 8, 9, 10, 12, 14, 15] """ i0, i1 = iter(s0), iter(s1) e0, e1 = next(i0), next(i1) "*** YOUR CODE HERE ***" def make_s(): """A generator function that yields all positive integers with only factors 2, 3, and 5. >>> s = make_s() >>> type(s) >>> [next(s) for _ in range(20)] [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36] """ "*** YOUR CODE HERE ***" def naturals(): """A generator function that yields the infinite sequence of natural numbers, starting at 1. >>> m = naturals() >>> type(m) >>> [next(m) for _ in range(10)] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] """ i = 1 while True: yield i i += 1