# 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, 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. Aug 15, 2017 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. Aug 16, 2017 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!. Aug 14, 2017 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! Aug 14, 2017 at 15:24

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. Aug 14, 2017 at 17:28

# Jelly, 9 bytes

+\S÷L<Ðf@


Try it online!

• Maybe <Ðf@ should instead be <Ðḟ@? Aug 14, 2017 at 15:04
• @EriktheOutgolfer but it passes all the testcases. Aug 14, 2017 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. Aug 14, 2017 at 15:15
• @EriktheOutgolfer In this context, filtering out means filtering for. Aug 14, 2017 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!

• I think you can do range(len(l)) and l[:i+1] for -2 bytes (not tested) Aug 14, 2017 at 15:09
• Golfed and obfuscated. ;) Thanks! Aug 14, 2017 at 15:12
• Your solution is invalid though. Change x>sum(...) to x<sum(...) for it to be valid, still 76 bytes Aug 14, 2017 at 15:13
• Wherps... Fixed. >.> Aug 14, 2017 at 15:13

# 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). Aug 15, 2017 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). Aug 15, 2017 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. Aug 14, 2017 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? Aug 14, 2017 at 15:28
• @officialaimm I think so, because enumeration values 1,2,3,... must go with x, x[-1], x[-2]. But in all cases the result seems to be the same, hmm... Aug 14, 2017 at 15:35
• I found a counterexample which shows that reversing is indeed necessary Aug 14, 2017 at 15:37
• Ah, never mind.. I just thought so because it passed all the test cases... :P Aug 14, 2017 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 Aug 14, 2017 at 15:06
• You can replace f<T with <# to save a byte. This may have been added to Pyth after this answer was posted, not sure. Apr 29, 2021 at 3:24

$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 :) Aug 15, 2017 at 0:46
• 12 bytes with #~]<1#.+/\%# Aug 15, 2017 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, 2017 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]&


# Factor, 36 bytes

[ dup cum-sum mean '[ _ < ] filter ]


Try it online!

## Explanation:

It's a quotation (anonymous function) that takes a sequence from the data stack as input and leaves a sequence on the data stack as output. Assuming { 1 4 -3 10 } is on the data stack when this quotation is called...

• dup Duplicate an object.

Stack: { 1 4 -3 10 } { 1 4 -3 10 }

• cum-sum Take the cumulative sum.

Stack: { 1 4 -3 10 } { 1 5 2 12 }

• mean Take the mean.

Stack: { 1 4 -3 10 } 5

• '[ _ < ] filter Take the elements from a sequence that are less than the number on top of the stack.

Stack: { 1 4 -3 }

# 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


# Jelly, 6 bytes

<ƇÄS÷ɗ


Try it online!

Takes the list on the left and its length on the right, as explicitly permitted.

With newer builtins, Leaky Nun's +\S÷L<Ðf@ becomes ÄS÷L<Ƈ@ (which may as well be ÄS÷L>x@, using one less piece of the present, but that's besides the point), but taking the length as the right argument trades an L and an @ for one ɗ.

 Ƈ        Filter the left argument to elements which
<         are less than
S ɗ    the sum of
Ä       the cumulative sums of the left argument
÷     divided by the right argument.