def mutate(l, p):
    """mutate(list, probability) -> list

    Given a list of integers and a mutation probability, mutate the list
    by either adding or subtracting from some of the elements.  The
    mutated list is returned."""

    (p, q) = torat(p)
    m = [1] * 24 + [2] * 12 + [3] * 6 + [4] * 3 + [5] * 2 + [6] * 1
    def flip(x, p = p, q = q, m = m):
        if rng.flip(p, q):
            y = m[rng.random() % len(m)]
            if rng.flip(1, 2):
                return x + y
            return x - y
        return x

    return map(flip, l)
def cross(l1, l2, p):
    """cross(list, list, probability) -> list

    Take elements from one list until a crossover is made, then take
    elements from the other list, and so on, with the given probability
    of a crossover at each position.  The initial list is chosen at
    random from one of the two lists with equal probability.  The lists
    must be the same length."""

    l = [0] * len(l1)
    x = map(None, l1, l2)
    j = rng.random() % 2
    (p, q) = torat(p)
    for i in xrange(len(l1)):
        if rng.flip(p, q):
            j = 1 - j
        l[i] = x[i][j]

    return l