r"""
Python module for OEIS sequence number A078758.

Term in A064389 (variation (4) of Recaman's sequence) where n appears,
or 0 if n never appears.

Examples of use.
-----------------------------------------------------------------------
>>> from a078758 import *
>>> print a078758_list(15)
[1, 4, 2, 35, 33, 3, 5, 16, 14, 12, 10, 8, 6, 188, 58]
>>> # Calculate at most 187 terms of A064389; return None if n has not appeared.
>>> print a078758_list(15, 187)
[1, 4, 2, 35, 33, 3, 5, 16, 14, 12, 10, 8, 6, None, 58]
>>> # Calculate at most 188 terms of A064389; return None if n has not appeared.
>>> print a078758_list(15, 188)
[1, 4, 2, 35, 33, 3, 5, 16, 14, 12, 10, 8, 6, 188, 58]
>>> print a078758_offset
1
>>> for x in a078758_list_pairs(6):
...     print x
...
(1, 1)
(2, 4)
(3, 2)
(4, 35)
(5, 33)
(6, 3)
>>> print a078758(14)
188
>>> # Calculate at most 100 terms of A064389; return None if 14 has not appeared.
>>> print a078758(14, 100)
None
>>> # Calculate at most 200 terms of A064389; return None if 14 has not appeared.
>>> print a078758(14, 200)
188
-----------------------------------------------------------------------
"""

from itertools import islice, izip, count
from a064389 import a064389_gen

__all__ = ('a078758_offset', 'a078758_list', 'a078758_list_pairs', 'a078758', 'a064389_gen')
__author__ = 'Nick Hobson <nickh@qbyte.org>'

a078758_offset = offset = 1

def a078758_list(n, p=None):
    """Returns a list of the first n >= 0 terms.

    If parameter p is passed, at most p iterations are performed; if n has
    not appeared then a(n) is set to None.
    """
    if n < 0: raise ValueError, 'Input n must be a non-negative integer'
    if p is not None and p < 1: raise ValueError, 'Input p must be a positive integer'
    prange = count(1) if p is None else xrange(1, p+1)
    r, t = [None] * n, 0
    for (k, x) in izip(prange, a064389_gen()):
        if x <= n and r[x-1] is None:
            r[x-1] = k
            t += 1
        if t == n: break
    return r

def a078758_list_pairs(n, p=None):
    """Returns a list of tuples (n, a(n)) of the first n >= 0 terms.


    If parameter p is passed, at most p iterations are performed; if n has
    not appeared then a(n) is set to None.
    """
    if n < 0: raise ValueError, 'Input n must be a non-negative integer'
    if p is not None and p < 1: raise ValueError, 'Input p must be a positive integer'
    return list(izip(xrange(offset, n+offset), a078758_list(n, p)))

def a078758(n, p=None):
    """Returns the term with index n >= 1; offset 1.

    If parameter p is passed, at most p iterations are performed; if n has
    not appeared then a(n) is set to None.
    """
    if n < offset: raise ValueError, 'Input n must be an integer >= offset = ' + str(offset)
    if p is not None and p < 1: raise ValueError, 'Input p must be a positive integer'
    prange = count(1) if p is None else xrange(1, p+1)
    for (k, x) in izip(prange, a064389_gen()):
        if x == n:
            return k
    return None