Find sequences of digits in long integers efficiently

integer, pattern-matching, performance, python, sequence

Solution

You can use this class to have your generator of digits :-)

import math

class DecimalIndexing:
    def __init__(self, n):
        self.n = n
    def __len__(self):
        return int(math.floor(math.log10(self.n)+1))
    def __getitem__(self, i):
        if isinstance(i, slice):
            return [self[x] for x in range(i.start, i.stop, i.step or 1)]
        else:
            return (self.n/(10**i))%10
    def __iter__(self):
        for i in xrange(len(self)):
            yield self[i]

you can use it like this:

di = DecimalIndexing(31415927)
for i in xrange(len(di)):
    if di[i:i+4] == [9,5,1,4]:
        print "found"

or like this:

for i in xrange(len(di)):
    if di[i:i+3] == [di[i]]*3:
        print "group of three equal digits at," i

or like this:

if 5 in di:
    print "has a five"

or like this:

if any(x > 5 in di):
    print "some digit was greater than five"

etc.

Keep in mind that the digits indices are "reversed", i.e. read from right to left.

Problem

Is it possible to find a defined sequence in an integer without converting it to a string? That is, is it possible to do some form of pattern matching directly on integers. I have not thought of one but I keeping thinking there should be a mathematical way of doing this. That's not to say it is more efficient. (edit) I actually what numbers that don't contain the sequences of digits I am looking for. The integers will be large, at least 289 digits. The sequences to find could be anything, "123", "5"(there is a five), "66666" I am interested in a general solution but if you would like to help with the acutal problem I am trying to sovle keep reading. More specifically I am looking for repeating digits of length 4 ie 1324322223313 "2222". I am staring with integers because I will be incrementing though consecutive integers unless I get to an integer with 4 length repeat then I would skip to the the next integer without the repeat. Also I don't what integers with digit larger that 4 ie 12322135 (it has a 5) would be excluded. The problem might also be stated as. Find all integers in the z = range(x,y) such that z[a] does not contain any repeating digits of length 4 and a digit larger than 4. The range(x,y) may be very large (Edit) in response to the comment, Yes I would actually like to generate a list, the problem I have is that I am not sure how I could make a generator that satisfies all the conditions I have. Maybe I should think about this more, I agree it would be simpler, but it might be similar to a generator for prime numbers, there is no such generator.

Original source