use std::ops::{Add,Sub};
use rstats::{here,MinMax};
use anyhow::{Result,bail};
use indxvec::merge::{sortm,minmax};
pub fn naive_median<T>(s:&[T]) -> Result<f64>
where T: PartialOrd+Copy+Add<Output=T>,f64:From<T> {
let n = s.len();
match n {
0 => bail!("{} can not take median of zero length vector!",here!()),
1 => return Ok(f64::from(s[0])),
2 => return Ok(f64::from(s[0]+s[1])/2.0),
_ => {}
}
let v = sortm(s,true);
let mid = n/2;
Ok(if (n & 1) == 0 { f64::from(v[mid-1] + v[mid]) / 2.0 }
else { f64::from(v[mid]) })
}
fn balance<T>(set:&[T],pivot:f64) -> i32
where T: PartialOrd+Copy+Sub<Output=T>,f64:From<T> {
set.iter().map(|&st| {
let s = f64::from(st);
if s>pivot { 1 } else if s<pivot { -1 } else { 0 }}).sum::<i32>()
}
pub fn newmedian<T>(s:&[T]) -> Result<i32>
where T: PartialOrd+Copy+Sub<Output=T>,f64:From<T> {
let MinMax{min,max,..} = minmax(s);
let pivot = f64::from(max-min)/2.0;
let bal = balance(s,pivot);
Ok(bal)
}