#ifndef __MONKEY_FIT__
#define __MONKEY_FIT__

#include <math.h>
#include <iterator>
#include <map>
#include <deque>
#include <algorithm>

#include "point.h"

struct fit_k
{
	static const int KN=200;

	std::map<int,int> probab_k; //k值的分布
	uint64_t point_count=0;

	fit_k() 
	{
	}

	void remove(const std::string&card_id)
	{
		points_.erase(card_id);
	}

	void push(const point&pt)
	{
		c.push(time_second,dist_meter);

		double k;
		for(int i=0,kc=c.k_count();i<kc;i++)
		{
			if(k=c.random_k())
			{
				++point_count;
				++probab_k[round(k*KN)];
			}
		}
	}

	double get_K()const
	{
		return get_probab_max(probab_k.begin(),probab_k.end(),point_count)/KN;
	}

	template<typename T> 
	static double get_probab_max(T it,T ite,int sum,int N=3)
	{
		sum/=5;
		sum=max(3,sum);

		std::vector<std::tuple<T,T,float>> p;


		if(N==0)
		{
			auto it0=it;
			for(int i=0;it0!=ite;++it0,++i)
			{
				if(i%10==0) printf("\n");

				printf("%5d:%2d,",it0->first,it0->second);
			}
			printf("\n");
		}

		int s=0;
		for(auto i1=it;it!=ite;)
		{
			for(;s<sum && i1!=ite;++i1)
				s+=i1->second;

			if(s<sum) break;

			p.push_back(std::make_tuple(it,i1,1.*s/(std::prev(i1)->first-it->first+1)));

			s-=it->second; ++it;
		}

		std::sort(p.begin(),p.end(),[](const std::tuple<T,T,int>&l,const std::tuple<T,T,int>&r){
				return 1.*std::get<2>(l) > 1.*std::get<2>(r);
				});

		int i=1;

		auto it1=std::get<0>(p[0]);
		auto it2=std::prev(std::get<1>(p[0]));

		for(;i<p.size();++i)
		{
			if(std::get<2>(p[i])!=std::get<2>(p[i-1]))
				break;

			if(std::get<0>(p[i])->first < it1->first)
				it1=std::get<0>(p[i]);

			if(std::prev(std::get<1>(p[i]))->second > it2->second)
				it2=std::prev(std::get<1>(p[i]));
		}

		++it2;

		double rc=0;
		int    cc=0;
		int    x=0;
		for(;it1!=it2;++it1)
		{
			rc+=it1->first*it1->second;
			cc+=it1->second;

			if(N==0)
			{
				if(x++%10==0) printf("\n");
				printf("%5d:%2d,",it1->first,it1->second);
			}
		}

		if(N==0)
			printf("\n");

		return rc/cc;
	}
};


#endif


