In this Kata, you will be given a string of numbers in sequence and your task will be to return the missing number. If there is no number
missing or there is an error in the sequence, return `-1`.

For example:
```Haskell
missing("123567") = 4 
missing("899091939495") = 92
missing("9899101102") = 100
missing("599600601602") = -1 -- no number missing
missing("8990919395") = -1 -- error in sequence. Both 92 and 94 missing.
```
The sequence will always be in ascending order.

More examples in the test cases. 

Good luck!

Source: codewars | Difficulty: EASY
Tags: String algorithms

Starter code: def missing(s):
	

Solutions:
def missing(seq):
	for digits in range(1, len(seq) // 2 + 1):
		my_seq = last = seq[:digits]
		n = int(my_seq)
		missing = None
		while len(my_seq) < len(seq):
			n += 1
			my_seq += str(n)
			if not seq.startswith(my_seq):
				if missing == None:
					missing = n
					my_seq = last
				else:
					break
			else:
				last = my_seq
		if my_seq == seq and missing:
			return missing
	return -1


def missing(s):
	i = 1
	while True:
		(start, missing, j) = (int(s[:i]), [], i)
		number = start + 1
		while j <= len(s) - len(str(number)):
			if int(s[j:j + len(str(number))]) != number:
				missing.append(number)
			else:
				j += len(str(number))
			number += 1
			if len(missing) > 1:
				break
		else:
			if not missing:
				return -1
			return missing[0]
		i += 1


def missing(s):
	for k in range(1, 7):
		(p, n, l, gaps) = (s, int(s[:k]), k, [])
		while p:
			p = p[l:]
			if p.startswith(str(n + 1)):
				(l, n) = (len(str(n + 1)), n + 1)
			elif p.startswith(str(n + 2)):
				gaps += [n + 1]
				(l, n) = (len(str(n + 2)), n + 2)
			else:
				break
		if len(gaps) == 1 and p == '':
			return gaps.pop()
	return -1


def missing(s):
	for i in range(1, len(s) // 2 + 1):
		(save, j, miss) = (int(s[:i]), i, None)
		while j < len(s):
			(x, y) = (str(save + 1), str(save + 2))
			if s[j:].startswith(x):
				j += len(x)
				save = int(x)
			elif s[j:].startswith(y) and miss is None:
				j += len(y)
				save = int(y)
				miss = int(x)
			else:
				miss = None
				break
		if miss is not None:
			return miss
	return -1


def missing(s):
	for i in range(1, len(s) // 2 + 1):
		(n, missing) = (int(s[:i]), None)
		while i < len(s):
			n += 1
			j = len(str(n))
			if s.startswith(str(n)[:len(s) - i], i):
				i += j
			elif missing:
				missing = None
				break
			else:
				missing = n
		else:
			if not missing:
				return -1
		if missing:
			return missing
	return -1


def missing(s):
	for nd in range(1, min(7, len(s) // 2 + 1)):
		(guess, miss) = (s[:nd], '')
		n = int(guess)
		while len(guess) < len(s):
			n += 1
			guess += str(n)
			if not s.startswith(guess):
				if miss:
					miss = ''
					break
				miss = str(n)
				guess = guess[:-len(miss)]
		if miss:
			return int(miss)
	return -1


class State:

	def __init__(self, pos, missing_candidate, expected1, expected2):
		self.pos = pos
		self.missing_candidate = missing_candidate
		self.expected1 = expected1
		self.expected2 = expected2
		self.valid = None

	def update_found_seq(self):
		self.pos += len(str(self.expected1))
		self.expected1 += 1
		self.expected2 = self.expected1 + 1

	def update_found_skip(self):
		self.missing_candidate = self.expected1
		self.pos += len(str(self.expected2))
		self.expected1 = self.expected2 + 1
		self.expected2 = self.expected1 + 1

	def __str__(self):
		return 'State({0}, {1}, {2}, {3})'.format(self.pos, self.missing_candidate, self.expected1, self.expected2)

def missing(s):
	res = -1
	for l in range(1, len(s) // 3 + 1):
		q = State(0, None, int(s[0:l]), 0)
		while q.pos < len(s) and q.valid == None:
			if s[q.pos:].startswith(str(q.expected1)):
				q.update_found_seq()
			elif not q.missing_candidate and s[q.pos:].startswith(str(q.expected2)):
				q.update_found_skip()
			else:
				q.valid = False
			if q.pos == len(s):
				q.valid = True
		if q.valid:
			if q.missing_candidate:
				res = q.missing_candidate
			else:
				res = -1
			break
	return res


def missing(s):

	def missing(s, base, candidate=-1):
		(head, tail) = (int(s[:base]), s[base:])
		if tail.startswith(str(head + 1)):
			return missing(tail, len(str(head + 1)), candidate)
		if tail.startswith(str(head + 2)):
			return missing(tail, len(str(head + 2)), head + 1) if candidate == -1 else -1
		return candidate if tail == '' else -1
	for base in range(1, len(s) // 2 + 1):
		result = missing(s, base)
		if result != -1:
			return result
	return -1


def missing(s):
	result = -1
	for start_chunk in range(1, len(s) // 2 + 1):
		res = inner(s, start_chunk)
		if res != -1:
			result = res
	return result

def inner(s, start_chunk):
	result = -1
	nums = []
	rest = s
	rip_count = 0
	last = int(rest[:start_chunk])
	rest = rest[start_chunk:]
	nums.append(last)
	chunk = start_chunk
	while rest != '':
		if int(rest[:chunk]) - last != 1:
			if int(rest[:chunk + 1]) - last == 1:
				chunk += 1
				print('chunk +=1')
			elif int(rest[:chunk + 1]) - last == 2:
				chunk += 1
				rip_count += 1
				print('chunk +=1')
				print('rip_count+=1')
				result = last + 1
			elif int(rest[:chunk]) - last == 2:
				rip_count += 1
				print('rip_count+=1')
				result = last + 1
			else:
				return -1
		nums.append(int(rest[:chunk]))
		last = int(rest[:chunk])
		rest = rest[chunk:]
		print(nums)
		if rip_count > 1:
			return -1
	return result