In this kata, your task is to write a function that returns the smallest and largest integers in an unsorted string. In this kata, a range is considered a finite sequence of consecutive integers.
Input
Your function will receive two arguments:

A string comprised of integers in an unknown range; think of this string as the result when a range of integers is shuffled around in random order then joined together into a string
An integer value representing the size of the range

Output
Your function should return the starting (minimum) and ending (maximum) numbers of the range in the form of an array/list comprised of two integers.

Test Example

```python
input_string = '1568141291110137'

mystery_range(input_string, 10) # [6, 15]

# The 10 numbers in this string are:
# 15 6 8 14 12 9 11 10 13 7
# Therefore the range of numbers is from 6 to 15
```


Technical Details

The maximum size of a range will be 100 integers
The starting number of a range will be: 0 < n < 100
Full Test Suite: 21 fixed tests, 100 random tests
Use Python 3+ for the Python translation
For JavaScript, require has been disabled and most built-in prototypes have been frozen (prototype methods can be added to Array and Function)
All test cases will be valid

If you enjoyed this kata, be sure to check out my other katas

Source: codewars | Difficulty: EASY
Tags: Ad-hoc

Starter code: def mystery_range(s,n):
	

Solutions:
from collections import Counter

def mystery_range(s, n):
	(i, target) = (-1, Counter(s))
	sum_ = sum(map(Counter, map(str, range(n))), Counter())
	while True:
		i += 1
		sum_ = sum_ - Counter(str(i)) + Counter(str(i + n))
		if sum_ == target:
			if len(str(i + 1)) < len(str(i + n)) or str(i + 1) in set(map(''.join, zip(*[iter(s)] * len(str(i + 1))))):
				return [i + 1, i + n]


from collections import Counter

def mystery_range(s, n):
	counts = Counter(s)
	for num in range(1, 100):
		if counts == Counter(''.join(map(str, range(num, num + n)))):
			if all((str(i) in s for i in range(num, num + n))):
				return [num, num + n - 1]


def mystery_range(s, n):
	ones = int((3 * n - 90 - len(s)) / 2)
	if '100' in s and ones > 0:
		hundreds = int((len(s) - 180 - ones) / 3)
		return [10 - ones, 99 + hundreds]
	elif '100' in s:
		hundreds = len(s) - 2 * n
		tens = n - hundreds
		return [100 - tens, 99 + hundreds]
	elif '10' in s:
		tens = len(s) - n
		ones = n - tens
		return [10 - ones, 9 + tens]
	elif len(s) == n:
		nums = list(map(int, s))
		return [min(nums), max(nums)]
	elif len(s) == 2 * n:
		nums = [int(s[i:i + 2]) for i in range(0, len(s), 2)]
		return [min(nums), max(nums)]


def mystery_range(s, n):
	t = len(s) - 180
	m = n - 90
	(x, xr) = divmod(3 * m - t, 2)
	(y, yr) = divmod(t - m, 2)
	if 0 <= m <= t <= 3 * m and xr == 0 and (yr == 0):
		return [10 - x, 99 + y]
	(q, r) = divmod(len(s), n)
	if r != 0:
		return [10 ** q - n + r, 10 ** q - 1 + r]
	seq = [int(s[i * q:(i + 1) * q]) for i in range(0, n)]
	return [min(seq), max(seq)]


def mystery_range(s, n):
	for i in range(1, 100):
		if sorted(list(s)) == sorted(list(''.join((str(x) for x in list(range(i, i + n)))))) and str(i) in s:
			return [i, i + n - 1]


def mystery_range(s, n):
	l = len(s)
	d = l - 2 * n
	if d == 0 and n < 90:
		ls = [10 * int(s[i]) + int(s[i + 1]) for i in range(0, l, 2)]
		return [min(ls), max(ls)]
	if abs(d) < n - 90:
		return [10 - (n - 90 - d) / 2, 99 + (n - 90 + d) / 2]
	if d < 0:
		return [10 + d, 9 + d + n]
	if d > 0:
		return [100 + d - n, 99 + d]


def string_from_range(x, y):
	while True:
		yield ''.join(sorted(list(''.join((str(i) for i in range(x, y))))))
		x += 1
		y += 1

def mystery_range(s, n):
	string = ''.join(sorted(list(s)))
	start = 0
	gen = string_from_range(start, start + n)
	for _ in range(10):
		if string == next(gen):
			return [start, start + n - 1]
		start += 1
	if len(s) % n == 0:
		(begin, lenth, temp_list) = (0, len(s) // n, [])
		for _ in range(n):
			temp_list.append(int(s[begin:begin + lenth]))
			begin += lenth
		temp_list.sort()
		return [temp_list[0], temp_list[-1]]
	for _ in range(100):
		if string == next(gen):
			return [start, start + n - 1]
		start += 1


from collections import Counter

def check(s, t):
	return not s or any((check(s[d:], t - {d}) for d in range(max(map(len, t)) + 1) if s[:d] in t))

def mystery_range(s, n):
	for i in range(1, 100):
		t = Counter(''.join(map(str, range(i, i + n))))
		if Counter(s) == Counter(t):
			return [i, i + n - 1] if check(s, set(map(str, range(i, i + n)))) else [i + 1, i + n]


def mystery_range(s, n):
	ss = sorted(s)
	for i in range(1, 100):
		jj = sorted(''.join((str(k) for k in range(i, i + n))))
		if jj == ss:
			if all((str(j) in s for j in range(i, i + n - 1))):
				return [i, i + n - 1]


def mystery_range(string, length_of_range, numbers_already_found=[]):
	if string == '':
		return [min(numbers_already_found), max(numbers_already_found)]
	for next_number_length in [1, 2, 3]:
		if len(string) < next_number_length or string.startswith('0'):
			return False
		next_number_candidate = int(string[:next_number_length])
		if next_number_candidate not in numbers_already_found and (numbers_already_found == [] or (next_number_candidate - min(numbers_already_found) < length_of_range and max(numbers_already_found) - next_number_candidate < length_of_range)):
			result = mystery_range(string[next_number_length:], length_of_range, numbers_already_found + [next_number_candidate])
			if result != False:
				return result
	return False