def find_triangles(radius):
    radius2 = radius ** 2
    # generate points in circle, except origin
    r = range(-radius + 1, radius)
    points = set()
    for x in r:
        for y in r:
            if mag2(x, y) < radius2:
                points.add((x, y))
    points.remove((0,0))

    #print(points)
    triangles = set()
    for p1, p2 in all_pairs(points):
        # test if p1-p2 crosses the origin
        if cmp_line(p1, p2, (0,0)) == 0:
            continue
        # get the set of points p3 that is on the side of the line p1-(0,0)
        # farthest from p2, and likewise for p2-(0,0). each of these points
        # completes a triangle (p1, p2, p3) that contains the origin.
        #TODO prevent duplication of triangles, reducing reliance on sets
        p3_set = (partition(points, p1, (0,0), p2)[1] &
                  partition(points, p2, (0,0), p1)[1])
        for p3 in p3_set:
            triangles.add(frozenset((p1, p2, p3)))
    return len(triangles)
def find_arithmetic_sequences(numbers, length):
    """
    Find arithmetic sequences in the given numbers of the specified length or longer.
    >>> list(find_arithmetic_sequences([1, 2, 3], 3))
    [(1, 2, 3)]
    >>> list(find_arithmetic_sequences([1, 3, 2], 3))
    [(1, 2, 3)]
    >>> list(find_arithmetic_sequences([1, 4, 5, 9, 10], 3))
    [(1, 5, 9)]
    """
    numbers = sorted(numbers)
    numbers_set = set(numbers)
    for a, b in all_pairs(numbers):
        assert a < b
        sequence = [a, b]
        diff = b - a
        c = b + diff
        while c in numbers_set:
            sequence.append(c)
            c = c + diff
            if len(sequence) >= length:
                yield tuple(sequence)
                break
def all_cuts(points, size):
    cuts = set()
    for a, b in all_pairs(points):
        cuts.add(tuple(sorted((a, b))))
    return set(c for c in cuts if is_legal_cut(*c, size=size))