You will be given a certain array of length ```n```, such that ```n > 4```, having positive and negative integers but there will be no zeroes and all the elements will occur once in it.

We may obtain an amount of ```n``` sub-arrays of length ```n - 1```, removing one element at a time (from left to right). 

For each subarray, let's calculate the product and sum of its elements with the corresponding absolute value of the quotient, ```q = SubProduct/SubSum``` (if it is possible, SubSum cannot be 0). 
Then we select the array with the lowest value of ```|q|```(absolute value)

e.g.: we have the array, ```arr = [1, 23, 2, -8, 5]```
```
Sub Arrays            SubSum    SubProduct         |q|
[23, 2, -8, 5]         22         -1840         83.636363
[1, 2, -8, 5]           0           -80          No value
[1, 23, -8, 5]         21          -920         43.809524
[1, 23, 2, 5]          31           230          7.419355  <--- selected array
[1, 23, 2, -8]         18           368         20.444444
```
Let's compare the given array with the selected subarray:
```
[1, 23, 2, -8, 5]
[1, 23, 2,     5]
```
The difference between them is at the index ```3``` for the given array, with element ```-8```, so we put both things for a result ```[3, -8]```.

That means that to obtain the selected subarray we have to take out the value -8 at index 3.
We need a function that receives an array as an argument and outputs the the pair ```[index, arr[index]]``` that generates the subarray with  the lowest value of ```|q|```.

```python 
select_subarray([1, 23, 2, -8, 5]) == [3, -8]
```
Another case:
```python 
select_subarray([1, 3, 23, 4, 2, -8, 5, 18]) == [2, 23]
```
In Javascript the function will be ```selectSubarray()```.

We may have some special arrays that may have more than one solution as the one that follows below.
```python 
select_subarray([10, 20, -30, 100, 200]) == [[3, 100], [4, 200]]
```
If there is more than one result the function should output a 2Darray sorted by the index of the element removed from the array.

Thanks to Unnamed for detecting the special cases when we have multiple solutions.

Features of the random tests:
```
Number of tests = 200
length of the array, l, such that 20 <= l <= 100
```

Enjoy it!!

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Data structures

Mathematics

Starter code: def select_subarray(arr):
	

Solutions:
from functools import reduce
from operator import mul

def select_subarray(arr):
	total = sum(arr)
	m = reduce(mul, arr)
	qs = [(abs(m // x / (total - x)) if total - x else float('inf'), i) for (i, x) in enumerate(arr)]
	q = min(qs)
	result = [[i, arr[i]] for (x, i) in qs if x == q[0]]
	return result[0] if len(result) == 1 else result


from operator import mul
from functools import reduce

def select_subarray(array):
	l = []
	for i in array:
		arr = [j for j in array if j != i]
		if sum(arr):
			l.append((abs(reduce(mul, arr) / float(sum(arr))), array.index(i), i))
	c = [[j, k] for (i, j, k) in l if i == sorted(l)[0][0]]
	return c[0] if len(c) == 1 else c


from functools import reduce
from operator import mul

def select_subarray(a):
	sub = []
	for i in range(len(a)):
		t = a[:i] + a[i + 1:]
		p = reduce(mul, t)
		s = sum(t)
		if p and s:
			sub.append([abs(p / s), i, t])
	m = min(sub)[0]
	r = [i[1] for i in sub if i[0] == m]
	result = [[i, a[i]] for i in r]
	return result if len(result) > 1 else result[0]


import numpy as np

def calc_one(value, tot_sum, tot_prod):
	value[value == tot_sum] = np.nan
	return tot_prod / value / (tot_sum - value)

def select_subarray(arr):
	np_arr = np.array(arr).astype(np.float64)
	tot_sum = np_arr.sum()
	tot_prod = np_arr.prod()
	qs = np.apply_along_axis(calc_one, 0, np_arr, tot_sum, tot_prod)
	qs = np.abs(qs)
	min_ = np.nanmin(qs)
	where_min = np.where(qs == min_)[0]
	out = [[where, arr[where]] for where in where_min]
	return out if len(out) > 1 else out[0]


import operator
from functools import reduce

def min_in_dict(in_dict, original_arr):
	positions = []
	min_value = float('inf')
	for (key, val) in in_dict.items():
		if val == min_value:
			positions.append([original_arr.index(key), key])
		if val < min_value:
			min_value = val
			positions = []
			positions.append([original_arr.index(key), key])
	return positions

def select_subarray(arr):
	q = dict()
	for el in arr:
		temp = arr.copy()
		temp.remove(el)
		if sum(temp):
			q[el] = abs(reduce(operator.mul, temp, 1) / sum(temp))
	if len(min_in_dict(q, arr)) == 1:
		return min_in_dict(q, arr)[0]
	else:
		return min_in_dict(q, arr)


from functools import reduce

def select_subarray(arr):
	d = {}
	for i in range(len(arr)):
		x = arr[:i] + arr[i + 1:]
		(s, p) = (sum(x), reduce(lambda x, y: x * y, x))
		n = abs(p / s) if s != 0 else float('inf')
		d.setdefault(n, []).append([i, arr[i]])
	r = d.get(min(d))
	return r.pop() if len(r) == 1 else r


import math
from functools import reduce
import operator

def select_subarray(arr):
	q_vals = []
	for i in range(len(arr)):
		a = arr[:i] + arr[i + 1:]
		sum_a = sum(a)
		if sum_a == 0:
			q_vals.append(None)
		else:
			q_vals.append(math.fabs(reduce(operator.mul, a, 1) / sum_a))
	selected = min(filter(lambda x: x is not None, q_vals))
	indexes = [i for (i, x) in enumerate(q_vals) if x == selected]
	result = []
	for index in indexes:
		result.append([index, arr[index]])
	if len(result) == 1:
		return result[0]
	return result


def select_subarray(arr):
	s = 0
	p = 1
	for x in arr:
		s += x
		p *= x
	result = []
	q = None
	for (i, x) in enumerate(arr):
		if s != x:
			new_q = abs(p / x / (s - x))
			if not result or new_q < q:
				result = [[i, x]]
				q = new_q
			elif new_q == q:
				result.append([i, x])
	return result if len(result) > 1 else result[0]