# Compare the averages of my lists

## Getting the average of a list (e.g [2,6,7])

• Get the length of the list: [2,6,7] -> 3
• Sum the numbers in the list: 2 + 6 + 7 = 15.
• Divide the sum by their count: 15 / 3 = 5.

You should compare the averages of two lists of positive integers N and M, by returning a value if N has a higher average, another value if M has a higher average, and another one in case of a tie.

# I/O rules

All the standard Input and Output methods are allowed.

### Input

You may take input as two separate lists, a nested list, or anything else you consider suitable for the task. Please specify the format.

### Output

The values provided have to be distinct and must consist of at least one non-whitespace character. Also, they must be consistent between runs (a single value for N, a single value for M, a single value for Tie). Please specify those in your answer. The values can be non-empty Strings, Bool values, Integers, or anything you consider suitable.

# Specs

• The lists will not necessarily have equal length.

• You are guaranteed that the lists are non-empty.

# Test Cases

I chose the values N wins, M wins and Tie, which are pretty much self-evident.

N, M                     ->   Output     (Averages)

,                  -> N wins  (N has 7, M has 6 )
[4,5], [4,4]             -> N wins  (N has 4.5, M has 4)
[2,3,4], [4,5,6]         -> M wins  (N has 3, M has 5)
[4,1,3], [7,3,2,1,1,2]   -> Tie     (both have 2.666...)
[100,390,1], [89,82,89]  -> N wins  (N has 163.666..., M has 86.666...)
[92,892], [892,92]       -> Tie     (lists are basically identical)
[10,182], [12,78,203,91] -> Tie     (both have 96)


Default Loopholes apply. Explanations are encouraged! This is , so the shortest code in bytes wins!

• – Mr. Xcoder Jul 5 '17 at 17:55
• if my language of choice only supports integers, can I take input multiplied by 1000? That way the calculated averages would still be accurate to 3 decimal places – Skidsdev Jul 7 '17 at 10:28
• @Mayube Yes, that is allowed – Mr. Xcoder Jul 7 '17 at 10:29
• We have to return an output of at least 1 character. Does that mean we are required to return a character or a string? Or do you mean an output whose string value is of a least 1 character? – Olivier Grégoire Jul 7 '17 at 12:14
• @OlivierGrégoire The output given must be at least 1 character long (you cannot return an empty string, but can return any String of at least 1 character, and also any non-whitespace character). IT's up to you. – Mr. Xcoder Jul 7 '17 at 12:19

# Actually, 5 bytes

♂æi-s


Try it online!

1 for N > M, 0 for N = M, -1 for N < M.

Explanation:

♂æi-s Takes input in format [N, M]
♂æ    Map average
i   Dump to stack in reverse
-  Subtract
s Get sign


## Mathematica, 15 bytes

Order@@Mean/@#&


Try it online!

Function which expects a list of two lists. Mean/@# takes the arithmetic mean of each list in the input, then those means are passed into Order, which returns -1 if the first list wins, 0 if there is a tie, and 1 if the second list wins.

# JavaScript (ES6), 52 50 bytes

(Saved 2 bytes thanks to @Shaggy.)

Here are two 50-byte solutions:

f=(N,M,a=eval(N.join+)/N.length)=>M?(a-f(M))/0:a

(N,M,A=a=>eval(a.join+)/a.length)=>(A(N)-A(M))/0


Returns Infinity for N, -Infinity for M, and NaN for a tie.

The first solution may require a bit of explanation due to the recursion:

On the first call to the function, a is initialized as the average of the N array:

a=eval(N.join+)/N.length


M has a value at this point, so the first part of the conditional expression is called:

M ? (a-f(M))/0 : a  ----------     

The function is called within this expression, this time substituting M for N.

On this second call to the function, a is initialized as the average of N –– which was M in the previous call.

Since there is no second parameter during this call to the function, the second part of the conditional expression is triggered, which returns the average:

M ? (a-f(M))/0 : a  -- 

We can now understand the expression better:

(a - f(M)) / 0


It's:

(the average of N  minus  the average of M) divided by 0


The difference between the averages will be a positive number, a negative number, or 0.

Dividing the difference by 0 results in Infinity, -Infinity, or NaN – providing the three distinct values as required.

Test Cases:

f=(N,M,a=eval(N.join+)/N.length)=>M?(a-f(M))/0:a

console.log(f(,                  )) // N wins  (N has 7, M has 6 )
console.log(f([4,5], [4,4]             )) // N wins  (N has 4.5, M has 4)
console.log(f([2,3,4], [4,5,6]         )) // M wins  (N has 3, M has 5)
console.log(f([4,1,3], [7,3,2,1,1,2]   )) // Tie     (both have 2.666...)
console.log(f([100,390,1], [89,82,89]  )) // N wins  (N has 163.666..., M has 86.666...)
console.log(f([92,892], [892,92]       )) // Tie     (lists are basically identical)
console.log(f([10,182], [12,78,203,91] )) // Tie     (both have 96)

• Could you save a couple of bytes by moving A to the function parameters? – Shaggy Jul 5 '17 at 22:56

# Mathematica, 21 bytes

Sign[Mean@#-Mean@#2]&


1 for # wins, -1 for #2 wins, 0 for tie.

• or, equally long, Sign[#-#2&@@Mean/@#]& – Greg Martin Jul 6 '17 at 2:20

# MATL, 8 bytes

Soooo many modifiers (Y and Z). I can't find a way to make it shorter. sum / number_of_elements is three bytes. It might be a better way to do -ZS, but I can't find one.

YmiYm-ZS


Try it online!

           % Take first input implicitly
Ym         % Mean of that input
i        % Grab second input
Ym      % Mean of that input
-     % Subtract
ZS   % Sign


Returns 1 if the first input is larger, 0 if they tie, and -1 if the second input is larger.

# 05AB1E, 9 bytes

1 if M wins, -1 if N wins and 0 for a tie.

vyOyg/}.S


Try it online!

Explanation

v           # for each y in list of lists
yO         # sum y
yg       # get length of y
/      # divide
}     # end loop
.S   # compare


# Julia, 27 bytes

(x,y)->cmp(mean(x),mean(y))


Try it online!

Returns 1 if the first average is larger, -1 if second is, and 0 if they tie.

# Python 2, 43 bytes

lambda p:cmp(*[sum(l)*1./len(l)for l in p])


Try it online!

# Octave, 27 bytes

@(x,y)sign(mean(x)-mean(y))


Try it online!

Takes two vectors x.y as input, takes the mean of both vectors, and subtract one from the other. Get the sign of this, to get 1, 0 and -1 for the three different alternatives.

# Python 2, 49 bytes

lambda N,M:cmp(1.*sum(N)/len(N),1.*sum(M)/len(M))


Try it online

• "...[the three outputs] must be consistent between runs" – Jonathan Allan Jul 5 '17 at 18:20
• @JonathanAllan Fixed – mbomb007 Jul 5 '17 at 18:24

# APL (Dyalog), 11 bytes

Prompts for a list of two lists. Prints 1 if the left has higher average, 0 if they have the same average, and ¯1 if the right has higher average.

×-/(+/÷≢)¨⎕


Try it online!

⎕ prompt

()¨ apply the following tacit function to each:

+/ the sum

÷ divided by

≢ the tally

-/ insert (and evaluate) a minus between them

× signum

# Javascript, 816658 56 bytes

saved 15 bytes thanks to Luke

saved 2 bytes thanks to Justin Mariner

n=>m=>Math.sign((a=b=>eval(b.join+)/b.length)(m)-a(n))


Tie is 0, M is 1 and N is -1. Called using currying syntax, eg. f()()

• You can improve this by quite a few bytes: you can remove the variable assignment, you can use curry syntax, you can remove the alert, and you can easily sum arrays by using eval(a.join+). a=>(b=a.map(c=>eval(c.join+)/c.length))-b?b>b:0 for 61 bytes. It takes input as an array of arrays, and outputs 0 for a tie, true for M and false for N. – Luke Jul 5 '17 at 18:44
• why don't you post it as your own answer? – SuperStormer Jul 5 '17 at 18:52
• You could save two more bytes by inlining the function (a) the first time it's used: n=>m=>Math.sign((a=b=>eval(b.join+)/b.length)(m)-a(n)). – Justin Mariner Jul 5 '17 at 19:11

<?foreach($_GET as$v)$r[]=array_sum($v)/count($v);echo$r<=>$r;  Try it online! # PHP, 69 bytes <?=($s=array_sum)($a=$_GET)/count($a)<=>$s($b=$_GET)/count($b);  Try it online! spaceship operator -1 less then , 0 tie , 1 greater then # Haskell, 65 43 Bytes Saved 22 bytes thanks to nimi! a x=sum x/sum[1|_<-x] x#y=compare(a x)$a y


There has to be a much better way... But type conversions screwed me.

Usage

(#)  


Returns GT if the first argument wins, LT if the second argument wins, and EQ if they tie.

Try it online!

• No need to cast sum$x with f.. Also: length x can be replaced with sum[1|_<-x], so you can get rid off f completely: a x=sum x/sum[1|_<-x]. – nimi Jul 5 '17 at 21:46 • Ah nice! Didn't even think to do that. – Henry Jul 5 '17 at 21:47 • ... oh and in #: ...(a x)$a y. – nimi Jul 5 '17 at 21:49
• ... even better: go pointfree with your main function, then you can even save the name for it: (.a).compare.a. Usage : ( (.a).compare.a )  . – nimi Jul 5 '17 at 21:58

# Perl 6, 25 bytes

{sign [-] .map:{.sum/$_}}  Try it online! Takes a single argument, a two-element list of lists of numbers. Returns 1 if the first list has a greater average, -1 if the second list does, and 0 if the averages are equal. # JavaScript (ES6), 60 bytes a=>(b=(c=a.map(d=>eval(d.join+)/d.length)))-c)?b>0:0  Outputs 0 for Tie, true for N and false for M. # JavaScript (ES6), 60 54 bytes -6 bytes thanks to @Luke and @Neil (i,[x,y]=i.map(v=>eval(v.join+)/v.length))=>y-x&&x>y  Takes input as a 2-element array [N, M]. Outputs true, 0, or false for N, Tie, or M, respectively. ## Explanation (i, // input array: [N, M] [x,y] = // destructure assignment: set x and y to... i.map(v=> // the input values mapped as... eval(v.join+) // the sum, by joining the array with + / v.length // divided by the length ) ) => y-x && x>y // return 0 for tie, or the result of avg(N) > avg(M)  ## Test Snippet Input numbers separated by spaces/commas. f= (i,[x,y]=i.map(v=>eval(v.join+)/v.length))=>y-x&&x>y <div oninput="O.value=f([N.value,M.value].map(x=>x.split(/[ ,]+/)))">N <input id=N> M <input id=M></div> Out: <input id=O disabled> • You can probably save some bytes by replacing Math.sign(y-x) by y-x?x>y:0. Outputs 0 for Tie, true for N and false for M. – Luke Jul 5 '17 at 18:57 • x-y&&x>y perhaps? – Neil Jul 5 '17 at 18:59 • @Neil Nice, even better – Justin Mariner Jul 5 '17 at 19:03 # Pip, 13 bytes {$CM$+*a/#*a}  This is a function that takes a list of lists. Returns 1 if the first average is bigger, -1 if the second is bigger, 0 if tied. Run all test cases here. ### Background This solution makes heavy use of two of Pip's metaoperators: • $, fold. Take a binary operator and apply it between the elements of a list. For instance, + is addition, but $+ sums a list. Note that $ makes a binary operator into a unary operator.
• *, map. Take a unary operator and apply it to each element of a list. For instance, # gives the length of a list, but #* gives (a list of) the lengths of the list's items.
• These two metaoperators can be combined: $+* maps fold/plus over a list, summing each of the list's elements. The other thing to know about Pip is that a lot of operators work item-wise on lists by default. For instance, [1 2 3] * 5 gives [5 10 15]; [1 2 3] * [2 3 4] gives [2 6 12]; and [[1 2] [3 4]] * [5 6] gives [[5 10] [18 24]]. ### Explanation We'll use an example input of [[2 3 4] [2 3 4 6]]: • {...} Defines a function. The (first) argument is bound to the local variable a. • #*a Map # to the function's argument, getting the lengths of the sublists. Result: [3 4] • a/#*a Divide (the elements of) the sublists of a by their respective lengths. Result: [[0.667 1 1.333] [0.5 0.75 1 1.5]] • $+*a/#*a
Map $+ (fold on addition) to that result, summing the sublists. Result: [3 3.75] • $CM$+*a/#*a Fold on CM, which gives -1, 0, or 1 depending on the comparison of its two operands (like Python's cmp). Result: -1 (because 3 is smaller than 3.75). You can also define functions in Pip by writing expressions containing the identity function _. For example, _*_ is a function that squares its argument--syntactic sugar for {a*a}, and fewer bytes. However, there's a bug in the current version of the interpreter that prevents _ from working with the * metaoperator. Once that's fixed, this solution can be 11 bytes: $CM\$+*_/#*_.

# C (gcc), 91 98 bytes

u,v,j;f(x,y,a,b)int*a,*b;{for(u=v=0;x--;u+=a[x])for(j=0;j<y;)v+=b[j++];j=u*y-v;x=j>0?2:!j;}


Wrong place for C and probably the only answer that doesn't need division. At least the code is displayed without a slider.

Return 0,1,2 for M>N, M=N, M<N respectively. Takes input as length of M, length of N, M, N.

• Is taking length as an argument within the specs? Cuts significant code from a lot of these if it is. – Henry Jul 5 '17 at 21:05
• I don't know if there's another way for C to retrieve the length of an array. The length itself is more like an intrinsic part of array. – Keyu Gan Jul 6 '17 at 4:47

# Brachylog, 8 bytes

⟨+/l⟩ᵐ-ṡ


Try it online!

Outputs 1 if the first list has a bigger average, -1 is the second list has a bigger average, and 0 if they are tied.

### Explanation

     ᵐ        Map:
⟨   ⟩           Fork:
+                Sum…
/               …divided by…
l              …length
-      Subtract
ṡ     Sign


# Java, 105 bytes

s->s.stream().map(l->l.stream().reduce((i,j)->i+j).get()/l.size()).reduce((i,j)->Math.signum(i-j)).get();


Lambda that takes a nested list, as per allowable inputs.

Streams the list of lists, converts both to their averages, then returns the sign of the difference. 1 if the first list is larger, -1 if the second list is larger, 0 for a tie.

• Since "anything can be an input", just use Streams directly, like I did. – Olivier Grégoire Jul 7 '17 at 12:10

# R 38 34 bytes

function(a,b)sign(mean(a)-mean(b))


Function that takes as input two numeric vectors. Returns 1 if first list average is higher, 0 if they are the same and -1 if second list average is higher.

• Is this an anonymous function that can be called without assignment? I don't know R but if it is you don't need the f=. – Wheat Wizard Jul 6 '17 at 12:26
• @WheatWizard you are correct; additionally you can remove the {} from the function body. – Giuseppe Jul 6 '17 at 15:21
• Thanks for the input. It's my first attempt at codegolf. – zelite Jul 6 '17 at 15:22

# MATL, 6 bytes

Don't be so mean!*

!-ssZS


Input stack order:

M
N


Output:

 1 = N wins
-1 = M wins
0 = tie


Try it online!

!-ssZS
========
!           % transpose M
-          % N - M^T using elementwise subtraction and implicit expansion
s         % sum columns of the result
s        % sum the resulting row vector
ZS      % sign of the sum


*This answer was golfed without being mean to any poor, defenseless numbers.

# Java (OpenJDK 8), 76 62 bytes

a->b->Math.signum(a.average().orElse(0)-b.average().orElse(0))


Try it online!

Since the input can be anything, I decided to take IntStreams as input. You can get such an input from a standard int[] with Arrays.stream(array).

The output is 1 for "N wins", -1 for "M wins", and 0 for tie.

### Saves

• -14 bytes from insights of both @Zircon and @Xanderhall!
• The way you've chosen to take the input is really clever! – David Conrad Jul 7 '17 at 12:29
• @DavidConrad I actually had the long version of this answer since yesterday (just prepend java.util.Arrays.stream(array).map(java.util.Arrays::stream)). It's only when I re-read the question today that I thought this input format is as valid as any. – Olivier Grégoire Jul 7 '17 at 12:35
• Would .orElse(0) be a viable shortening of .getAsDouble()? – Zircon Jul 7 '17 at 14:21
• If you instead just take 2 streams for input, (a,b)->Math.signum(a.average().orElse(0)-b.average().orElse(0)); is 64 bytes – Xanderhall Jul 7 '17 at 14:41
• These are only good ideas, guys! Continue :p – Olivier Grégoire Jul 7 '17 at 14:48

# Dyalog APL, 14 bytes

×(-/(+/÷≢)¨∘⊢)


1 if the left is greater, ¯1 if the right is and 0 on tie.

How?

¨∘⊢ for each list

+/÷≢ calculate average (+/ sum ÷ divide by ≢ length)

-/ subtract the averages

× sign of the result

# Common Lisp, 74 71 bytes

(defun g(x)(/(apply'+ x)(length x)))(defun f(x y)(signum(-(g x)(g y))))


Try it online!