Specification: Return index of the first element you can remove that does not change the mean of the list by more than 0.1
Example input/output:
Input: vals
idvalue
01
12
23
31
Output: 1

Python - Imperative


def get_mean(ls):
  sum = 0
  for e in ls:
    sum += e['value']
  return sum/len(ls)

def changing_mean(vals):
  start_mean = get_mean(vals)
  for i,elem in enumerate(vals):
    new_ls = vals[:i] + vals[i+1:]
    mean = get_mean(new_ls)
    if abs(mean - start_mean) < 0.1:
      return i
  return None

Python - Functional


def changing_mean(vals):
  start_mean = sum([l['value'] for l in vals])/len(vals)
  diff = lambda m, sm: abs(m - sm)
    
  for i,elem in enumerate(vals):
    new_ls = [x['value'] for x in vals if x != elem]
    mean = sum(new_ls)/len(new_ls)
    if diff(mean,start_mean) < 0.1:
      return i
  return None

Python - Pandas


def changing_mean(vals):
  mean = vals.value.mean()
  mean_without = vals.apply(lambda row: vals[vals.id != row.id].value.mean(), axis=1)
  return vals[(mean_without - mean).abs() < 0.1].id.tolist()

R - Tidyverse

library(data.table)
changing_mean <- function(vals) {
   global_mean <- mean(vals$value)
   setDT(vals)[, 
     mean_change := abs(global_mean - mean(vals[id != .BY, value])), 
     by = id] %>%
     filter(mean_change < 0.1) %>%
     slice(which.min(id)) %>%
     pull(id)
}

SQL - SQLite

SELECT id
FROM vals v1
WHERE ABS((
  SELECT AVG(value)
  FROM vals v2
  WHERE v1.id != v2.id
) - (SELECT AVG(value) FROM vals)) < 0.1

Datalog - Souffle

.decl avg_except(I:number, Avg:float)    
avg_except(I, Avg) :- 
  vals(I, _),
  N = sum 1.0 : { vals(J, _), I != J },
  Total = sum V : { vals(J, V), I != J },
  Avg = Total / N.
  
changing_mean(I) :-
  vals(I, _),
  N = sum 1.0 : vals(_, _),
  Total = sum V : vals(_, V),
  Avg = Total / N,
  avg_except(I, AvgExcept),
  ((Avg > AvgExcept, Avg - AvgExcept < 0.1);
   (Avg < AvgExcept, AvgExcept - Avg < 0.1)).

Q - kdb+

diffs: 
  {abs avg vals[`value] - avg (vals[`value] where vals[`id] <> x)} 
  each vals[`id];
  
changing_mean: first vals[`id] where diffs < 0.1