r""" Python module for OEIS sequence number A000102. a(n) = number of compositions of n in which the maximum part size is 4. a(n) = 2*a(n-1) + a(n-2) - 2*a(n-4) - 3*a(n-5) - 2*a(n-6) - a(n-7). Examples of use. ----------------------------------------------------------------------- >>> from a000102 import * >>> print a000102_list(15) [0, 0, 0, 0, 1, 2, 5, 12, 27, 59, 127, 269, 563, 1167, 2400] >>> print a000102_offset 0 >>> for x in a000102_list_pairs(6): ... print x ... (0, 0) (1, 0) (2, 0) (3, 0) (4, 1) (5, 2) >>> a000102_list_upto(1000) [0, 0, 0, 0, 1, 2, 5, 12, 27, 59, 127, 269, 563] >>> print a000102(4) 1 ----------------------------------------------------------------------- """ from itertools import islice, izip, takewhile, count __all__ = ('a000102_offset', 'a000102_list', 'a000102_list_pairs', 'a000102_list_upto', 'a000102', 'a000102_gen') __author__ = 'Nick Hobson <nickh@qbyte.org>' a000102_offset = offset = 0 def a000102_gen(): """Generator function for OEIS sequence A000102.""" a = [0, 0, 0, 0, 1, 2, 5] for x in a: yield x for n in count(7): a[n%7] = 2*a[(n-1)%7] + a[(n-2)%7] - 2*a[(n-4)%7] - 3*a[(n-5)%7] - 2*a[(n-6)%7] - a[(n-7)%7] yield a[n%7] def a000102_list(n): """Returns a list of the first n >= 0 terms.""" if n < 0: raise ValueError, 'Input must be a non-negative integer' return list(islice(a000102_gen(), n)) def a000102_list_pairs(n): """Returns a list of tuples (n, a(n)) of the first n >= 0 terms.""" if n < 0: raise ValueError, 'Input must be a non-negative integer' return list(izip(xrange(offset, n+offset), a000102_gen())) def a000102_list_upto(m): """Returns a list of all terms not exceeding m >= 0.""" if m < 0: raise ValueError, 'Input must be a non-negative integer' return list(takewhile(lambda t: t <= m, a000102_gen())) def a000102(n): """Returns the term with index n >= 0; offset 0.""" if n < offset: raise ValueError, 'Input must be an integer >= offset = ' + str(offset) return list(islice(a000102_gen(), n-offset, n-offset+1)).pop()