15
\$\begingroup\$

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]
\$\endgroup\$
  • \$\begingroup\$ If some languages are allowed to take the length of the array as additional input, then it should be allowed for all languages. \$\endgroup\$ – ngenisis Aug 15 '17 at 22:13
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – Mr. Xcoder Aug 16 '17 at 5:43

24 Answers 24

7
\$\begingroup\$

MATL, 8 bytes

ttYsYm<)

Try it online! Or verify all test cases.

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
\$\endgroup\$
7
\$\begingroup\$

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
\$\endgroup\$
  • 2
    \$\begingroup\$ ηOO¹g/›Ï for 8; also it starts with nOO!. \$\endgroup\$ – Magic Octopus Urn Aug 14 '17 at 17:30
5
\$\begingroup\$

Japt v2.0a0, 12 11 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.

\$\endgroup\$
4
\$\begingroup\$

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!

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

Jelly, 9 bytes

+\S÷L<Ðf@

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Maybe <Ðf@ should instead be <Ðḟ@? \$\endgroup\$ – Erik the Outgolfer Aug 14 '17 at 15:04
  • \$\begingroup\$ @EriktheOutgolfer but it passes all the testcases. \$\endgroup\$ – Leaky Nun Aug 14 '17 at 15:08
  • \$\begingroup\$ 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. \$\endgroup\$ – Erik the Outgolfer Aug 14 '17 at 15:15
  • \$\begingroup\$ @EriktheOutgolfer In this context, filtering out means filtering for. \$\endgroup\$ – Leaky Nun Aug 14 '17 at 15:22
3
\$\begingroup\$

Python 2, 78 76 71 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!

\$\endgroup\$
3
\$\begingroup\$

Haskell, 39 bytes

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).

\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
  • 2
    \$\begingroup\$ f</L⁰Σ∫⁰⁰ is 9 bytes, but three lambda arguments feels clunky. \$\endgroup\$ – Zgarb Aug 14 '17 at 17:28
3
\$\begingroup\$

JavaScript (ES6), 56 55 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>

\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 3 bytes by removing t/=l; and change if(n<t) to if(n<t/l). \$\endgroup\$ – Kevin Cruijssen Aug 15 '17 at 12:17
  • 1
    \$\begingroup\$ 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). \$\endgroup\$ – Nevay Aug 15 '17 at 14:19
2
\$\begingroup\$

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!

\$\endgroup\$
2
\$\begingroup\$

Python 3, 72 bytes

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

Try it online!

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

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).

\$\endgroup\$
  • \$\begingroup\$ Do you need to reverse the list? \$\endgroup\$ – officialaimm Aug 14 '17 at 15:28
  • \$\begingroup\$ @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... \$\endgroup\$ – Luis Mendo Aug 14 '17 at 15:35
  • 1
    \$\begingroup\$ I found a counterexample which shows that reversing is indeed necessary \$\endgroup\$ – Luis Mendo Aug 14 '17 at 15:37
  • \$\begingroup\$ Ah, never mind.. I just thought so because it passed all the test cases... :P \$\endgroup\$ – officialaimm Aug 14 '17 at 15:39
2
\$\begingroup\$

Perl 6, 31 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Pyth - 10 bytes

<#.OsM._QQ

Try it online here.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 12 11 bytes

f<T.OsM._QQ

-1 byte thanks to Mr. Xcoder

Try it online!

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

Perl 5, 51 + 1 (-a) = 52 bytes

$a+=$_*(@F-$c++)for@F;for(@F){print$_,$"if$_<$a/@F}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Röda, 46 41 39 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
  • 1
    \$\begingroup\$ you beat me to it by 3 mins :) \$\endgroup\$ – Jonah Aug 15 '17 at 0:46
  • \$\begingroup\$ 12 bytes with #~]<1#.+/\%# \$\endgroup\$ – miles Aug 15 '17 at 2:08
  • \$\begingroup\$ @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. \$\endgroup\$ – cole Aug 15 '17 at 2:11
1
\$\begingroup\$

R, 31 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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]&
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 9 bytes

Ans*(Ans<mean(cumSum(Ans
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.