#include <algorithm>
#include <random>
#include <iostream>
#include <array>
#include <math.h>

static const int N = 8;
typedef std::array<double,N> ArrayT;

void SetMTRandomValue(ArrayT& Data){
	std::mt19937 Rnd(1);
	std::uniform_real_distribution<double> Dist(0,65535);

	std::for_each(Data.begin(),Data.end(),[&](double& In){ In = pow(Dist(Rnd)*Dist(Rnd)*Dist(Rnd),1.0/3);});
	
}
void SetLARandomValue(ArrayT& Data){
	std::minstd_rand Rnd(1);
	std::uniform_real_distribution<double> Dist(0,65535);

	std::for_each(Data.begin(),Data.end(),[&](double& In){ In = pow(Dist(Rnd)*Dist(Rnd)*Dist(Rnd),1.0/3);});
	
}

void GetMinMax(ArrayT& Data,double& Min,double& Max){
	Min = Data[0];
	Max = Data[0];
	std::for_each(Data.begin(),Data.end(),[&](double& In){ 
		if(In>Max) Max=In;
		if(In<Min) Min=In;
	});
}

int CountRangeValue(ArrayT Data,double Value,double Range){
	double R= Range;
	int Count=0;
	std::for_each(Data.begin(),Data.end(),[&](double In){
		if(Value <= In && In < (Value+R)) Count ++;
	});
	return Count;
}

double MakeAve(ArrayT Data,double Val){
	int Count=0;
	double Total=0;
	std::for_each(Data.begin(),Data.end(),[&](double In){
		if(In<Val) {
			Total+= In;
			Count++;
		}
	}
	);
	return Total/Count;

}

int main(){
	ArrayT Data={5,4,3,6,7,8,12,13};
	double Min,Max;
	double NoiseP = 0.75;//何割くらいがノイズか。
	//SetMTRandomValue(Data);
	GetMinMax(Data,Min,Max);
	int C=0;
	double V = Min;
 
	double P=0; 
	for(int i=1;C<(Data.size()*NoiseP);i++){
		if(i==31) break;
		int B = (1<<i); 
		double D = (Max-Min)/B;
		C+= CountRangeValue(Data,V, D);
		V+= D;

		P = (V-Min)/(Max-Min);
	}
	double Ave = MakeAve(Data,Max*P);

	std::cout<<"ave:"<<Ave<<std::endl;
	return 0;

}