In this Kata, we define an arithmetic progression as a series of integers in which the differences between adjacent numbers are the same. You will be given an array of ints of `length > 2` and your task will be to convert it into an arithmetic progression by the following rule:
```Haskell
For each element there are exactly three options: an element can be decreased by 1, an element can be increased by 1 
or it can be left unchanged.
```
Return the minimum number of changes needed to convert the array to an arithmetic progression. If not possible, return `-1`.
```Haskell
For example: 
solve([1,1,3,5,6,5]) == 4 because [1,1,3,5,6,5] can be changed to [1,2,3,4,5,6] by making 4 changes.
solve([2,1,2]) == 1 because it can be changed to [2,2,2]
solve([1,2,3]) == 0  because it is already a progression, and no changes are needed.
solve([1,1,10) == -1 because it's impossible.
solve([5,6,5,3,1,1]) == 4. It becomes [6,5,4,3,2,1]
```

More examples in the test cases. Good luck!

Difficulty: EASY
Tags: Fundamentals

Starter code:
def solve(arr):
	

Solutions:
def solve(arr):
	res = []
	for first in (arr[0] - 1, arr[0], arr[0] + 1):
		for second in (arr[1] - 1, arr[1], arr[1] + 1):
			(val, step, count) = (second, second - first, abs(arr[0] - first) + abs(arr[1] - second))
			for current in arr[2:]:
				val += step
				if abs(val - current) > 1:
					break
				count += abs(val - current)
			else:
				res.append(count)
	return min(res, default=-1)


def solve(arr):

	def isProgression(array):
		prevstep = array[1] - array[0]
		for (j, v) in enumerate(array[1:]):
			curstep = array[j + 1] - array[j]
			if curstep != prevstep:
				return False
			prevstep = curstep
		return True
	if isProgression(arr):
		return 0
	lst = [arr]
	chg = [0]
	good = [isProgression(arr)]
	for j in range(len(arr)):
		for k in range(len(lst)):
			if j > 2 and isProgression(lst[k][:j - 1]) is not True:
				continue
			lstp1 = lst[k][:j] + [lst[k][j] + 1] + lst[k][j + 1:]
			lst.append(lstp1)
			chg.append(chg[k] + 1)
			good.append(isProgression(lstp1))
			lstm1 = lst[k][:j] + [lst[k][j] - 1] + lst[k][j + 1:]
			lst.append(lstm1)
			chg.append(chg[k] + 1)
			good.append(isProgression(lstm1))
	filtered_lst = [x for (j, x) in enumerate(lst) if good[j]]
	filtered_chg = [x for (j, x) in enumerate(chg) if good[j]]
	if len(filtered_lst) == 0:
		return -1
	return min(filtered_chg)


solve = lambda a, d={-1, 0, 1}: min((sum(l) for l in ([abs(a[0] + u + (a[1] + v - a[0] - u) * n - x) for (n, x) in enumerate(a)] for u in d for v in d) if set(l) <= d), default=-1)


solve = lambda a, d=(-1, 0, 1): min((sum(l) for l in ([abs(a[0] + u + q * n - x) for (n, x) in enumerate(a)] for u in d for (q, r) in (divmod(a[-1] + v - a[0] - u, len(a) - 1) for v in d) if r < 1) if all((x in d for x in l))), default=-1)


def solve(arr):
	n = len(arr)
	(k, s) = (n - 1, n + 1)
	d = arr[k] - arr[0]
	for d in range((d - 2) // k, (d + 2) // k + 1):
		for i in (-1, 0, 1):
			p = [abs(arr[0] + i + d * k - q) for (k, q) in enumerate(arr)]
			if max(p) < 2:
				s = min(s, sum(p))
	return -1 if s > n else s


def solve(arr):
	head = arr[0]
	tail = arr[-1]
	check = [(i, j) for i in range(head - 1, head + 2) for j in range(tail - 1, tail + 2)]
	possibles = []
	for (start, end) in check:
		if (end - start) % (len(arr) - 1) == 0:
			possibles.append((start, end))
	global_changes = float('inf')
	for (start, end) in possibles:
		diff = int((end - start) / (len(arr) - 1))
		if diff == 0:
			tester = [start] * len(arr)
		else:
			tester = list(range(start, end + diff, diff))
		current_changes = 0
		for i in range(len(tester)):
			if abs(tester[i] - arr[i]) > 1:
				current_changes = float('inf')
				break
			elif abs(tester[i] - arr[i]) == 1:
				current_changes += 1
		global_changes = min(current_changes, global_changes)
	return global_changes if global_changes != float('inf') else -1


import numpy as np

def solve(arr):
	l = len(arr)
	fst = arr[0]
	lst = arr[l - 1]
	diff_range = lst - fst
	diffs = []
	for diff in range(diff_range - 2, diff_range + 3):
		if diff == 0:
			diffs.append(diff)
		elif diff % (l - 1) == 0:
			diffs.append(diff)
	progs = []
	for diff in diffs:
		for i in range(-1, 2):
			for j in range(-1, 2):
				if fst + i + diff == lst + j:
					seq = []
					if diff == 0:
						seq = l * [fst + i]
					else:
						k = 1
						if diff < 0:
							k = -1
						seq = list(np.arange(fst + i, lst + j + k, diff / (l - 1)))
					if len(seq) == l:
						progs.append(seq)
	changes = []
	for seq in progs:
		change = 0
		complete = True
		for (a, b) in zip(seq, arr):
			diff = abs(a - b)
			if diff > 1:
				complete = False
				continue
			if diff != 0:
				change += 1
		if complete:
			changes.append(change)
	if len(changes) == 0:
		return -1
	return min(changes)


from itertools import product

def solve(arr):
	res = []
	for (p, q) in product([-1, 0, 1], repeat=2):
		step = (arr[-1] + q - (arr[0] + p)) / (len(arr) - 1)
		if step.is_integer():
			exp = range(arr[0] + p, arr[-1] + q + int(step), int(step)) if step else [arr[0] + p] * len(arr)
			res.append(sum((abs(a - e) if abs(a - e) in (0, 1) else float('inf') for (a, e) in zip(arr, exp))))
	return min(res) if min(res, default=float('inf')) != float('inf') else -1


def solve(a):
	r = []
	for i in range(-1, 2):
		for j in range(-1, 2):
			curr_diff = a[-1] - a[0] + j - i
			if curr_diff % (len(a) - 1) == 0:
				curr_a = [a[0] + i] + a[1:-1] + [a[-1] + j]
				k = curr_diff // (len(a) - 1)
				t = [abs(curr_a[0] + i * k - a[i]) for i in range(len(a))]
				if max(t) <= 1:
					r.append(sum(t))
	return min(r) if r else -1


def solve(ls):
	result = [ls[each] - ls[each - 1] for each in range(1, len(ls))]
	gap = round(sum(result) / len(result))
	tries = [ls[0] + 1, ls[0], ls[0] - 1]
	answer = []
	while True:
		count = 0
		copy_ls = ls[:]
		copy_ls[0] = tries.pop(0)
		if copy_ls[0] != ls[0]:
			count += 1
		for each in range(len(ls) - 1):
			sub_gap = copy_ls[each + 1] - copy_ls[each]
			if sub_gap < gap:
				copy_ls[each + 1] += 1
				count += 1
			elif sub_gap > gap:
				copy_ls[each + 1] -= 1
				count += 1
		result = [copy_ls[each] - copy_ls[each - 1] for each in range(1, len(ls))]
		if len(set(result)) == 1:
			answer.append(count)
		if len(tries) == 0:
			if len(answer) == 0:
				return -1
			else:
				answer.sort()
				return answer[0]