# One is the loneliest number

## Task

The range of vision of a digit is its own value. `1` can see one digit to the left and one digit to the right,` 2` can see two digits, and so on.

Thus, the loneliness of a digit `N` is the sum of the digits which it can see.

Given a non-negative integer, your funtion must determine if there's at least one digit `1` in this integer such that its loneliness value is minimal.

## Example

```
number = 34315
```

digit | can see on the left | can see on the right | loneliness
--- | --- | --- | ---
3 | - | 431 | 4 + 3 + 1 = 8
4 | 3 | 315 | 3 + 3 + 1 + 5 = 12
3 | 34 | 15 | 3 + 4 + 1 + 5 = 13
1 | 3 | 5 | 3 + 5 = 8
5 | 3431 | - | 3 + 4 + 3 + 1 = 11

Is there a `1` for which the loneliness is minimal? Yes.

Difficulty: EASY
Tags: Data structures

Ad-hoc
Skill types: Data structures

Starter code:
def loneliest(number):
	

Solutions:
def loneliest(n):
	a = list(map(int, str(n)))
	b = [(sum(a[max(0, i - x):i + x + 1]) - x, x) for (i, x) in enumerate(a)]
	return (min(b)[0], 1) in b


def loneliest(n):

	def loneliness(it):
		(i, v) = it
		return (sum(lst[max(0, i - v):i + v + 1]) - v, abs(v - 1))
	lst = list(map(int, str(n)))
	return 1 in lst and 1 == min(enumerate(lst), key=loneliness)[1]


def loneliest(number):
	digits = []
	while number:
		(number, rem) = divmod(number, 10)
		digits.append(rem)
	lowest = one = float('inf')
	for (i, d) in enumerate(digits):
		s = sum(digits[max(0, i - d):i + d + 1]) - d
		if d == 1:
			one = min(one, s)
		else:
			lowest = min(lowest, s)
	return one <= lowest and one != float('inf')


def loneliest(number):
	ints = [int(n) for n in str(number)]
	scores = [(sum(ints[max(0, i - d):i + d + 1]) - d, d) for (i, d) in enumerate(ints)]
	return (min(scores)[0], 1) in scores


def loneliest(number):
	seq = list(map(int, str(number)))
	temp = 0
	ans = 100
	ans1 = 100
	key = 0
	x = 0
	if seq.count(1) == 0:
		return False
	for i in seq:
		temp = sum(seq[x + 1:x + i + 1]) + sum(seq[x - i if x > i else 0:x])
		if i == 1:
			if temp < ans1:
				ans1 = temp
		elif temp < ans:
			ans = temp
		x += 1
	if ans1 <= ans:
		return True
	else:
		return False


def loneliest(number):
	numbers = [int(c) for c in str(number)]
	loneliness = [(n, sum(numbers[max(i - n, 0):i]) + sum(numbers[i + 1:i + 1 + n])) for (i, n) in enumerate(numbers)]
	onesLoneliness = [p[1] for p in loneliness if p[0] == 1]
	if not onesLoneliness:
		return False
	otherLoneliness = [p[1] for p in loneliness if not p[0] == 1]
	if not otherLoneliness:
		return True
	return min(otherLoneliness) >= min(onesLoneliness)


def loneliest(number):
	xs = [int(c) for c in str(number)]
	d = {i: sum(xs[max(i - x, 0):i] + xs[i + 1:i + 1 + x]) for (i, x) in enumerate(xs)}
	m = min(d.values())
	return any((xs[i] == 1 and d[i] == m for i in d))


def left(num, n, i):
	s = 0
	counter = 0
	index = i - 1
	while index >= 0 and counter < n:
		s += int(num[index])
		index -= 1
		counter += 1
	return s

def right(num, n, i):
	s = 0
	counter = n
	index = i + 1
	while index < len(num) and counter:
		s += int(num[index])
		index += 1
		counter -= 1
	return s

def _sum(num, n, i):
	return left(num, n, i) + right(num, n, i)

def compare(one, others):
	for other in others:
		if one > other:
			return False
	return True

def check(ones, others):
	for one in ones:
		yield compare(one, others)

def loneliest(number):
	num = str(number)
	if not '1' in num:
		return False
	ones = []
	others = []
	for i in range(len(num)):
		s = _sum(num, int(num[i]), i)
		print()
		if num[i] == '1':
			ones.append(s)
		else:
			others.append(s)
	return any(list(check(ones, others)))


def calculate_loneliness(s, ind):
	rng = int(s[ind])
	if ind - rng < 0:
		res_str = s[:ind] + s[ind + 1:ind + rng + 1]
		return sum([int(char) for char in res_str])
	res_str = s[ind - rng:ind] + s[ind + 1:ind + rng + 1]
	return sum([int(char) for char in res_str])

def loneliest(n):
	s = str(n)
	if '1' not in s:
		return False
	lone_list = []
	lst = []
	for i in range(len(s)):
		lone_list.append(calculate_loneliness(s, i))
		lst.append(int(s[i]))
	min_1 = lone_list[s.find('1')]
	for i in range(len(lone_list)):
		if lst[i] == 1:
			if lone_list[i] < min_1:
				min_1 = lone_list[i]
	if min(lone_list) == min_1:
		return True
	return False


def loneliest(number):
	if str(number).count('1') == 0:
		return False
	if str(number).count('1') == len(str(number)):
		return True
	number = [int(a) for a in str(number)]
	score = []
	one = []
	for (idx, nr) in enumerate(number):
		b = idx - nr
		f = idx + nr + 1
		s = 0
		if b < 0:
			b = 0
		if f > len(number):
			f = len(number)
		s += sum(number[b:idx])
		s += sum(number[idx + 1:f])
		if nr == 1:
			one.append(s)
		else:
			score.append(s)
	score.sort()
	one.sort()
	if score[0] >= one[0]:
		return True
	return False