# Average out two lists

### Challenge

Given two lists of positive integers, determine whether it is possible to rearrange the elements into two new lists such that the new lists have the same arithmetic mean (average).

### Input

The input can be taken through STDIN or as function arguments. Input can be taken as a list, or if your language doesn't support lists (or anything similar such as arrays/dictionaries) then the input can be taken as a comma- or space-delimited string. That is,

"1 4 8 2 5,3 1 5 2 5"


is the same as:

[ [1,4,8,2,5], [3,1,5,2,5] ]


All input lists will be the same length.

### Output

If you can create two new lists with the same average, your program/function should print or return the mean. If you can't, your program should output a sad face :(.

Note that the rearranged lists with equal means, if they exist, need not has the same length. Any number of swaps can be made to create the new lists.

### Examples

1 4 8 2 5,3 1 5 2 5 -> 1 4 8 2 3,5 1 5 2 5 (swapped 3 and 5) -> 3.6
1 3 6 2,16 19 19 14 -> [[1,6,19,14],[3,2,16,19]] -> 10
2 6 2,6 3 5 -> 2 6,2 6 3 5 (moved 2) -> 4
90 80 20 1,40 60 28 18 -> :(


This is so shortest code in bytes wins. As always, standard loopholes are disallowed.

• Can we swap any number of elements from each list? Can one list just give elements to the other? I don't understand what you mean by "valid permutation exists". Also, this needs more test cases.
– xnor
Jul 29 '15 at 19:26
• @xnor you can just move one element, to another. I'll add a few more test cases Jul 29 '15 at 19:27
• So, is this equivalent to, "Given a single list (their union), can in be partitioned into two nonempty lists with the same average ?"
– xnor
Jul 29 '15 at 19:28
• @vihan1086 Why not take a single list as input then? Your presentation seems needlessly complicated.
– xnor
Jul 29 '15 at 19:30
• @vihan1086 Looking at your Sandbox post, many of these same requests for clarification were made there, and you said you clarified many of these points, but your edits didn't really make them clearer. You would have been better off replacing the confusing text rather than adding further text.
– xnor
Jul 29 '15 at 19:34

# Pyth, 24 bytes

?}KcsJsQlJmcsdldtPyJK":(


Try it online: Demonstration

Thanks to Dennis for noticing an error and golfing one byte.

### Explanation:

?}KcsJsQlJmcsdldtPyJK":(   implicit: Q = evaluated input
sQ                   all numbers of Q
J                     save them in J
KcsJ  lJ                 average of J (sum(J) / len(J))
store in K
m     tPyJ       map each nonempty subset d of J to:
csdld             average of d
?}                         if K in ^:
K        print K

• Nice work, +1. But does Pyth really not have a built-in for computing the mean? Jul 29 '15 at 20:36
• @AlexA. It now does have one (namely .O) Oct 15 '17 at 19:53

# SWI-Prolog, 159 bytes

a(A,B):-append([A,B],R),permutation(R,S),append([Y,Z],S),sum_list(Y,I),sum_list(Z,J),length(Y,L),length(Z,M),L\=0,M\=0,I/L=:=J/M,W is J/M,write(W);write(':(').


Called as a([1,4,8,2,5],[3,1,5,2,5]).

# Julia, 101 bytes

f(a,b)=(m=mean;p=filter(i->m(i[1])==m(i[2]),partitions([a,b],2));isempty(p)?":(":m(collect(p)[1][1]))


This creates a function that accepts two arrays and returns a string or a float accordingly.

Ungolfed + explanation:

function f(a,b)
# Get the set of all 2-way partitions of the array [a,b]
l = partitions([a,b], 2)

# Filter the set of partitions to those where the two
# contained arrays have equal means
p = filter(i -> mean(i[1]) == mean(i[2]), l)

# Return a frown if p is empty, otherwise return a mean
isempty(p) ? ":(" : mean(collect(p)[1][1])
end


# R, 94 Bytes

Basically the same as Jakubes I think. If the mean of both lists matches the mean of any combination of the values in lists up to but not including the combined length of the list, output the mean otherwise the sad face.

if(mean(l<-scan())%in%unlist(sapply(2:length(l)-1,function(x)combn(l,x,mean))))mean(l)else':('


Test run

> if(mean(l<-scan())%in%unlist(sapply(2:length(l)-1,function(x)combn(l,x,mean))))mean(l)else':('
1: 1 4 8 2 5
6: 3 1 5 2 5
11:
[1] 3.6
> if(mean(l<-scan())%in%unlist(sapply(2:length(l)-1,function(x)combn(l,x,mean))))mean(l)else':('
1: 90 80 20 1
5: 40 60 28 18
9:
[1] ":("


# Jelly, 23 bytes

FŒ!ŒṖL=2ƊƇÆmEƇƲ€ṀṀṀȯ⁾:(


Try it online!

Wildly inefficient, times out when the lengths of the input lists are $$\\ge4\$$

## How it works

FŒ!ŒṖL=2ƊƇÆmEƇƲ€ṀṀṀȯ⁾:( - Main link. Takes a list of lists, l = [a,b]
F                       - Flatten
Œ!                     - Yield all permutations
Ʋ€        - Over each permutation, p:
ŒṖ                   -   Yield all partitions of p
L=2ƊƇ              -   Only keep those of length 2
Æm            -   Take the mean of each
EƇ          -   Only keep those where the means are equal
ṀṀṀ     - Take the maximum three times. This yields 0 for impossible inputs and the mean for possible ones
⁾:( - Yield the string ":("
ȯ    - Replace 0 with this string, or do nothing if not 0

• Fails for 2 6 2,6 3 5 -> 2 6,2 6 3 5 (moved 2) -> 4. You're only splitting it into two parts of equal length now. Aug 10 '18 at 11:13
• @KevinCruijssen very late, but fixed Oct 5 '20 at 21:57