# Task
 Given an array `arr` and a number `n`. Call a pair of numbers from the array a `Perfect Pair` if their sum is equal to `n`.

 Find all of the perfect pairs and return the sum of their **indices**. 
 
 Note that any element of the array can only be counted in one Perfect Pair. Also if there are multiple correct answers, return the smallest one.

# Example

 For `arr = [1, 4, 2, 3, 0, 5] and n = 7`, the result should be `11`.
 
 Since the Perfect Pairs are `(4, 3)` and `(2, 5)` with indices `1 + 3 + 2 + 5 = 11`.

 For `arr = [1, 3, 2, 4] and n = 4`, the result should be `1`.
 
 Since the element at `index 0` (i.e. 1) and the element at `index 1` (i.e. 3) form the only Perfect Pair.

# Input/Output


 - `[input]` integer array `arr`

  array of non-negative integers.


 - `[input]` integer `n`

  positive integer


 - `[output]` integer

  sum of indices and 0 if no Perfect Pair exists.

Difficulty: introductory

Starter code:

def pairwise(arr, n):
	

Solutions:
def pairwise(arr, n):
    s=[]
    for i in range(len(arr)-1):
        for j in range(i+1,len(arr)):
            if j in s or i in s: continue
            if arr[i]+arr[j] ==n:
                s.append(i)
                s.append(j)
    return sum(s)

def pairwise(arr, n):

    iMap, s = {}, 0
    for i,x in enumerate(arr): iMap[x] = iMap.get(x, []) + [i]
    
    for x in arr:
        if n-x in iMap and len(iMap[n-x]) > (x == n-x) < len(iMap[x]):
            s += iMap[x].pop(0)
            s += iMap[n-x].pop(0)
    return s

def pairwise(arr, n):
    seen = set()
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            if arr[i] + arr[j] == n and not (i in seen or j in seen):
                seen.add(i)
                seen.add(j)
                break
    return sum(seen)

def pairwise(arr, n):
    # fiond each pair of elements that add up to n in arr
    a, i, j, pairs = sorted(arr), 0, len(arr) - 1, []
    while i < j:
        tot = a[i] + a[j]
        if tot == n:
            pairs.extend([a[i], a[j]])
            i, j = i + 1, j - 1
        elif tot < n:
            i += 1
        else:
            j -= 1
    pairs.sort()
    
    # Identify the lowest possible index for each element in pairs
    indices = []
    i, last = 0, None
    for x in pairs:
        # Continue from last found if repeat value else from start of array
        i = (indices[-1] + 1) if x == last else 0
        indices.append(arr.index(x, i))
        last = x
    
    return sum(indices)

# This isn't best practice, this is just for fun
def pairwise(arr, n):
    save = set()
    add = save.add
    return sum(i+j if x+y==n and not (i in save or add(j) or add(i)) else 0 for i,x in enumerate(arr) if i not in save for j,y in enumerate(arr[i+1:], i+1) if j not in save)

def pairwise(arr, n):
    result = 0
    for i in range(len(arr)):
        d = n - arr[i]
        if d in arr[i+1:]:
            j = arr.index(d, i+1)
            result += i + j
            arr[i] = arr[j] = n + 1
    return result


from collections import defaultdict

def pairwise(arr,n):
    ixs=defaultdict(list)
    for i,e in enumerate(arr): ixs[e].append(i)
    h=n/2
    t=sum(x+y for a,ai in (p for p in ixs.items() if p[0]<h) for x,y in zip(ai,ixs.get(n-a,[])))
    if n%2: return t
    hi=ixs.get(int(h),[])
    return t+sum(hi[:len(hi)//2*2])

def pairwise(arr, n):
    used = []
    for i in range(len(arr)-1):
        for j in range(i+1, len(arr)):
            if arr[i] + arr[j] == n and not (i in used or j in used):
                used.extend([i, j])
    return sum(used)

from itertools import combinations

def pairwise(arr, n):
    r,c = 0,[]
    for (i,a),(j,b) in combinations(enumerate(arr),2):
        if a+b == n and i not in c and j not in c:
            r += i+j
            c.extend([i,j])
    return r

def pairwise(arr, n):
    lst = [[e, i] for i, e in enumerate(arr)]
    ans, v = [], []
    for i, e in enumerate(arr):
        if i in v:
            continue
        for j, e2 in enumerate(arr[i+1:]):
            x = i+1+j
            if e + e2 == n and x not in v:
                v.append(i)
                v.append(x)
                ans.append((i,x))
                break
    return sum([i[0]+i[1] for i in ans]) if ans != [] else 0