You can't simply loop over set sizes, you have parse, using a changing size.
Take n characters from the start of the string, convert them to int, add one, and check if it matches the new start of the string. If not, record that, add the characters back to the start of the string and try again. Repeat. If the number of non-matches gets greater than 1, stop, add one to n, and try the whole process again. If you get through a whole loop at n and the number of non-matches is 1, then you've found the correct answer.
def split(sequence, x):
return sequence[:x], sequence[x:]
def parse(digits):
"""
Try to parse "digits" into numbers, and find the missing one.
The numbers will have no more than six digits.
Return -1 if "digits" isn't parseable or isn't missing one.
>>> parse("89101113") # 8, 9, 10, (12), 13
12
>>> parse("9899101102") # 98, 99, (100), 101, 102
100
>>> parse("596597598600601602") # 596, 597, 598, (599), 600, 601, 602
599
>>> parse("909192939495969798100101") # 90, ...
99
>>> parse("11111211311411511") # Looks like "111, ..." but isn't
-1
"""
for n in range(1, 7):
expected, remainder = split(digits, n)
failures = []
while len(failures) <= 1 and remainder:
expected = str(int(expected) + 1)
actual, remainder = split(remainder, len(expected))
if actual != expected:
failures.append(expected)
remainder = actual + remainder # Re-parse
if len(failures) == 1:
return int(failures[0])
return -1