# Kata Task

Given a list of random integers, return the Three Amigos.

These are 3 numbers that live next to each other in the list, and who have the **most** in common with each other by these rules:
* lowest statistical range
* same parity

# Notes

* The list will contain at least 3 numbers
* If there is more than one answer then return the first one found (reading the list left to right)
* If there is no answer (e.g. no 3 adjacent numbers with same parity) then return an empty list.

# Examples

* ex1
 * Input = ```[1, 2, 34, 2, 1, 5, 3, 5, 7, 234, 2, 1]```
 * Result = ```[5,3,5]```
 

* ex2
 * Input = ```[2, 4, 6, 8, 10, 2, 2, 2, 1, 1, 1, 5, 3]```
 * Result = ```[2,2,2]```
 

* ex3
 * Input = ```[2, 4, 5, 3, 6, 3, 1, 56, 7, 6, 3, 12]```
 * Result = ```[]```

Difficulty: EASY
Starter code: def three_amigos(numbers):
	

Solutions:
def three_amigos(numbers):
	return min(([a, b, c] for (a, b, c) in zip(numbers, numbers[1:], numbers[2:]) if a & 1 == b & 1 == c & 1), key=lambda triple: max(triple) - min(triple), default=[])


three_amigos = lambda a: (sorted(((max(a[i:i + 3]) - min(a[i:i + 3]), a[i:i + 3]) for i in range(len(a) - 2) if a[i] % 2 == a[i + 1] % 2 == a[i + 2] % 2), key=lambda x: x[0]) + [(None, [])])[0][1]


from collections import defaultdict

def three_amigos(numbers):
	candidates = defaultdict(list)
	for i in range(len(numbers) - 2):
		triplet = numbers[i:i + 3]
		if len({n % 2 for n in triplet}) == 1:
			candidates[max(triplet) - min(triplet)].append(triplet)
	return candidates[min(candidates)][0] if candidates else []


from collections import defaultdict

def three_amigos(numbers):
	amigos = defaultdict(list)
	for i in range(len(numbers) - 3 + 1):
		(a, b, c) = numbers[i:i + 3]
		if a % 2 == b % 2 == c % 2:
			rnge = max(a, b, c) - min(a, b, c)
			amigos[rnge].append([a, b, c])
	return amigos[min(amigos.keys())][0] if amigos else []


import sys

def three_amigos(numbers):
	p1 = 0
	min_range = sys.maxsize
	output = None
	for idx in range(3, len(numbers) + 1):
		slice = numbers[p1:idx]
		p1 += 1
		if sameParity(slice):
			minmax = max(slice) - min(slice)
			if minmax < min_range:
				min_range = minmax
				output = slice
	return output if output else []

def sameParity(arr):
	even = True if arr[0] % 2 == 0 else False
	for idx in range(1, len(arr)):
		if even and arr[idx] % 2 != 0:
			return False
		if not even and arr[idx] % 2 == 0:
			return False
	return True


def three_amigos(a):
	li = []
	for i in range(len(a) - 2):
		s = a[i] & 1
		t = a[i:i + 3]
		if all((j & 1 == s for j in t)):
			m = max(t)
			m_ = min(t)
			li.append([m - m_, t])
	return min(li, key=lambda x: x[0], default=[[], []])[1]


def three_amigos(numbers):
	it = (xs for xs in zip(numbers, numbers[1:], numbers[2:]) if len({x % 2 for x in xs}) == 1)
	return list(min(it, key=lambda xs: max(xs) - min(xs), default=()))


def three_amigos(numbers):
	return list(min((a for a in zip(numbers, numbers[1:], numbers[2:]) if sum((b % 2 for b in a)) in [0, 3]), key=lambda x: max(x) - min(x), default=[]))


three_amigos = lambda l: min(([a, b, c] for (a, b, c) in zip(l, l[1:], l[2:]) if a % 2 == b % 2 == c % 2), key=lambda t: max(t) - min(t), default=[])


three_amigos = lambda a: min([[max(a[i:i + 3]) - min(a[i:i + 3]), a[i:i + 3]] for i in range(len(a) - 2) if all((j & 1 == a[i] & 1 for j in a[i:i + 3]))], key=lambda x: x[0], default=[[], []])[1]