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.