Filter out the pseudo-elements!

We define the hyper-average of an array / list (of numbers) the arithmetic mean of the sums of its prefixes.

For example, the hyper-average of the list [1, 4, -3, 10] is computed in the following manner:

• We get the prefixes: [1], [1, 4], [1, 4, -3], [1, 4, -3, 10].

• Sum each: [1, 5, 2, 12].

• And now get the arithmetic mean of the elements in this list: (1 + 5 + 2 + 12) / 4 = 5.

A pseudo-element of an array is an element whose value is strictly lower than its hyper-average. Hence, the pseudo-elements of our example list are 1, 4 and -3.

Given a list of floating-point numbers, your task is to return the list of pseudo-elements.

• You don't have to worry about floating-point inaccuracies.

• The input list will never be empty and it may contain both integers and floats. If mentioned, integers may be taken as floats (with <integer>.0)

• You may assume that the numbers fit your language of choice, but please do not abuse that in any way.

• Optionally, you may take the length of the array as input as well.

• This is , so standard rules for the tag apply. The shortest code in bytes (in each language) wins!

Test Cases

Input -> Output

[10.3] -> []
[5.4, 5.9] -> [5.4, 5.9]
[1, 4, -3, 10] -> [1, 4, -3]
[-300, -20.9, 1000] -> [-300, -20.9]
[3.3, 3.3, 3.3, 3.3] -> [3.3, 3.3, 3.3, 3.3]
[-289.93, 912.3, -819.39, 1000] -> [-289.93, -819.39]

• If some languages are allowed to take the length of the array as additional input, then it should be allowed for all languages. – ngenisis Aug 15 '17 at 22:13
• @ngenisis It is for all languages. If taking the length as well shortens your program, feel free to do it. That spec isn't language restrictive at all. – Mr. Xcoder Aug 16 '17 at 5:43

MATL, 8 bytes

ttYsYm<)


Explanation

tt    % Implicitly input array. Duplicate twice
Ys    % Cumulative sum
Ym    % Arithmetic mean
<     % Less than? (element-wise). Gives an array containing true / false
)     % Reference indexing : use that array as a mask to select entries
% from the input. Implicitly display


05AB1E, 9 8 bytes

-1 bytes thanks to Magic Octopus Urn

ηOO¹g/‹Ï


Try it online!

η        # Get prefixes
O       # Sum each
O¹g/   # Get the mean ( length(prefix list) equals length(original list) )
‹Ï # Keep only the value that are less than the mean


05AB1E, 6 bytes

Using the new ÅA command.

ηOÅA‹Ï


Try it online!

η      # Get prefixes
O     # Sum each
ÅA   # Get the mean
‹Ï #  Keep only the value that are less than the mean

• ηOO¹g/›Ï for 8; also it starts with nOO!. – Magic Octopus Urn Aug 14 '17 at 17:30

Japt v2.0a0, 1211 10 bytes

f<Uå+ x÷Ul


Test it

• 1 byte saved thanks to ETH pointing out a redundant character.

Explanation

Implicit input of array U.

f<


Filter (f) the array by checking if each element is less than ...

Uå+


U cumulatively reduced (å) by summing ...

x


With the resulting array in turn reduced by summing ...

/Ul


And divided by the length (l) of U.

Implicitly output the resulting array.

Python 3 with Numpy, 48 bytes

lambda x:x[x<mean(cumsum(x))]
from numpy import*


Input and output are Numpy arrays. Try it online!

• +1 Finally, someone uses cumsum! – Mr. Xcoder Aug 14 '17 at 15:24

Jelly, 9 bytes

+\S÷L<Ðf@


Try it online!

• Maybe <Ðf@ should instead be <Ðḟ@? – Erik the Outgolfer Aug 14 '17 at 15:04
• @EriktheOutgolfer but it passes all the testcases. – Leaky Nun Aug 14 '17 at 15:08
• Still something doesn't seem good to me...first of all +\S÷L calculates the hyper-average, then <Ðf@ puts it as its right argument and < will return 1 if an element is a pseudo-element, essentially filtering for the pseudo-elements instead of filtering them out. – Erik the Outgolfer Aug 14 '17 at 15:15
• @EriktheOutgolfer In this context, filtering out means filtering for. – Leaky Nun Aug 14 '17 at 15:22

Python 2, 787671 66 bytes

-7 bytes thanks to Mr. Xcoder.

lambda l:[x for x in l if x<sum(sum(l[:i])for i in range(len(l)))]


Try it online!

f l=filter(<sum(scanl1(+)l)/sum(1<$l))l  Try it online! Unfortunately length is of type Int, so I cannot use it with floating point division / and I have to use a workaround: sum(1<$l).

Husk, 10 9 bytes

Thanks @Zgarb for golfing off 1 byte!

f</L⁰Σ∫⁰⁰


Try it online!

Ungolfed/Explanation

           -- argument is ⁰ (list)
f       ⁰  -- filter the original list with
<         --   element strictly smaller than
Σ∫⁰   --   sum of all prefixes
/L⁰      --   averaged out

• f</L⁰Σ∫⁰⁰ is 9 bytes, but three lambda arguments feels clunky. – Zgarb Aug 14 '17 at 17:28

JavaScript (ES6), 5655 52 bytes

a=>a.filter(x=>x<t/a.length,a.map(x=>t+=s+=x,s=t=0))


Test it

o.innerText=(f=

a=>a.filter(x=>x<t/a.length,a.map(x=>t+=s+=x,s=t=0))

)(i.value=[1,4,-3,10]);oninput=_=>o.innerText=f(i.value.split,.map(eval))
<input id=i><pre id=o>

Java 8, 81 bytes

This lambda expression accepts a List<Float> and mutates it. The input list's iterator must support removal (ArrayList's does, for example). Assign to Consumer<List<Float>>.

a->{float l=0,t=0,u;for(float n:a)t+=n*(a.size()-l++);u=t/l;a.removeIf(n->n>=u);}


Ungolfed lambda

a -> {
float l = 0, t = 0, u;
for (float n : a)
t += n * (a.size() - l++);
u = t / l;
a.removeIf(n -> n >= u);
}


Try It Online

Acknowledgments

• -3 bytes thanks to Kevin Cruijssen
• -17 bytes thanks to Nevay
• You can save 3 bytes by removing t/=l; and change if(n<t) to if(n<t/l). – Kevin Cruijssen Aug 15 '17 at 12:17
• You can use a list instead of an array to be able to modify the provided argument rather than printing the resulting values a->{float l=0,t=0,u;for(float n:a)t+=n*(a.size()-l++);u=t/l;a.removeIf(n->n>=u);} (81 bytes). – Nevay Aug 15 '17 at 14:19

C# (Mono), 95 bytes

using System.Linq;a=>a.Where(d=>d<new int[a.Length].Select((_,i)=>a.Take(i+1).Sum()).Average())


Try it online!

Python 3, 72 bytes

lambda x:[*filter((sum(-~a*b for a,b in enumerate(x))/len(x)).__gt__,x)]


Try it online!

• Very clever solution! I never thought filter would win over the usual list comprehension. – Mr. Xcoder Aug 14 '17 at 15:14

Python 3, 76 bytes

lambda x:[w for w in x if w<sum(u*v+v for u,v in enumerate(x[::-1]))/len(x)]


Input and output are lists of numbers. Try it online!

This works in Python 2 too (with the obvious replacement for print syntax in the footer).

• Do you need to reverse the list? – officialaimm Aug 14 '17 at 15:28
• @officialaimm I think so, because enumeration values 1,2,3,... must go with x[0], x[-1], x[-2]. But in all cases the result seems to be the same, hmm... – Luis Mendo Aug 14 '17 at 15:35
• I found a counterexample which shows that reversing is indeed necessary – Luis Mendo Aug 14 '17 at 15:37
• Ah, never mind.. I just thought so because it passed all the test cases... :P – officialaimm Aug 14 '17 at 15:39

Perl 6, 31 bytes

{.grep(flat([\,] $_).sum/$_>*)}


Try it online!

Pyth - 10 bytes

<#.OsM._QQ


Pyth, 12 11 bytes

f<T.OsM._QQ


-1 byte thanks to Mr. Xcoder

Try it online!

• 11 bytes: f<T.OsM._QQ – Mr. Xcoder Aug 14 '17 at 15:06

$a+=$_*(@F-$c++)for@F;for(@F){print$_,$"if$_<$a/@F}  Try it online! PHP, 84 bytes for($i=--$argc;$i;)$s+=$i--/$argc*$r[]=$argv[++$k];foreach($r as$x)$x<$s&&print\$x._;


takes input from command line arguments. Run with -nr or try it online.

summing up the partial lists is the same as summing up each element multiplied with the number of following elements +1 → no need to juggle with bulky array functions. It´s still long, though.

Röda, 4641 39 bytes

f l{l|[_]if[_1*#l<seq(1,#l)|l[:_]|sum]}


Try it online!

J, 15 bytes

#~[<[:(+/%#)+/\


Try it online! Expects a J-style array (negatives represented using _ instead of - and elements separated by spaces -- see the TIO link for examples).

I don't know if there's a way to remove the parentheses around the mean (+/%#) but removing that and the cap would be the first thing I'd try to do to golf this further.

Explanation

Sometimes J reads like (obfuscated) English.

#~ [ < [: (+/ % #) +/\
+/\  Sum prefixes
\   Get prefixes
+/    Sum each
(+/ % #)      Mean
+/            Sum of array
%          Divided by
#        Length of array
[ <                  Input array is less than?
(gives boolean array of pairwise comparisons)
#~                      Filter by

• you beat me to it by 3 mins :) – Jonah Aug 15 '17 at 0:46
• 12 bytes with #~]<1#.+/\%# – miles Aug 15 '17 at 2:08
• @miles Unless you think it's similar enough, I think your comment might warrant its own answer. EDIT: I think it's very clever myself. – cole Aug 15 '17 at 2:11

R, 31 bytes

function(l)l[l<mean(cumsum(l))]


Try it online!

Mathematica, 35 bytes

Cases[#,x_/;x<#.Range[#2,1,-1]/#2]&


Function which expects a list of numbers as the first argument # and the length of the list as the second argument #2. #.Range[#2,1,-1]/#2 takes the dot product of the input list # and the the list Range[#2,1,-1] == {#2,#2-1,...,1}, then divides by the length #2. Then we return the Cases x_ in the input list # which are less than the hyper-average.

Without the length as a second argument, we need 6 more bytes:

Cases[#,x_/;x<#.Range[h=Tr[1^#],1,-1]/h]&


K (oK), 26 bytes

Solution:

x@&x<(+/+/'x@!:'1+!#x)%#x:


Try it online!

Examples:

> x@&x<(+/+/'x@!:'1+!#x)%#x:1 4 -3 10
1 4 -3
> x@&x<(+/+/'x@!:'1+!#x)%#x:-289.93 912.3 -819.39 1000
-289.93 -819.39


Explanation:

Interpretted right-to-left. Struggled with a short way to extract prefixes:

x@&x<(+/+/'x@!:'1+!#x)%#x: / the solution
x: / store input in x, x:1 4 -3 10
#   / count, return length of x, #1 4 -3 10 => 4
(               )     / do everything in the brackets together
#x      / count x
!        / til, range 0..x, !4 => 0 1 2 3
1+         / add 1 vectorised, 1+0 1 2 3 => 1 2 3 4
!:'           / til each, e.g. !1, !2, !3, !4
x@              / index into x at these indices (now we have the prefixes)
+/'                / sum (+ over) each, e.g. 1 5 2 12
+/                   / sum over, e.g. 20
%    / right divided by left, 20%4 => 5 (now we have the hyper average)
x<                      / boolean list where x less than 5
&                        / indices where true, &0111b => 1 2 3
x@                         / index into x at these indices (now we have the filtered list)


Notes:

Alternative version taking length of input as parameter (25 byte solution):

> {x@&x<(+/+/'x@!:'1+!y)%y}[1 4 -3 10;4]
1 4 -3


TI-Basic, 9 bytes

Ans*(Ans<mean(cumSum(Ans