#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<time.h>

#define user 100
#define id 220970
int k=0,p=0;
int lnumber=0,lprofile=0;
int    *s_data;
double *simi;
int neardata=0;
double zz = 0.0;


typedef struct ratings {
	int number;
	int profile;
	int rate;
};  

void SetMyData(ratings *mydata);
void SetData(ratings *data,int k);
void GetData(ratings *data , ratings *alldata ,int k, int s);
void Similarity(ratings *data , ratings *mydata);
void Simil(ratings *data , double *simil);

int main(void)
{
	char filename[] = "ratings.dat";
	FILE *fp;
	int d_number,d_profile,d_rate;
	int i,s;
	i = s = 0;
	clock_t start,end;
	double time = 0.0;

	ratings    *alldata;
	alldata = (ratings*)malloc(sizeof(ratings) * 17359347);
	ratings    *data;
	data = (ratings*)malloc(sizeof(ratings) * user * id);
	ratings    *mydata;
	mydata = (ratings*)malloc(sizeof(ratings) * id);
	s_data = (int*)malloc(sizeof(int) * id);
	simi = (double*)malloc(sizeof(double) * user);

	printf("memorykeep\n");

	/* ファイル・オープン */
	if ((fp = fopen("ratings.dat", "r")) == NULL)
	{
		printf("ファイル「%s」のオープンに失敗しました。プログラムを終了します。\n", filename);
		exit(1);
	}

	i=0;

	while (fscanf(fp, "%d,%d,%d", &d_number, &d_profile, &d_rate) != EOF)
	{
		alldata[i].number = d_number;
		alldata[i].profile = d_profile;
		alldata[i].rate = d_rate;
		i++;
	}

	lnumber = d_number;
	lprofile = d_profile;

	printf("fileread\n");
	/* ファイル・クローズ */

	SetMyData(mydata);

	printf("start\n");
	while(alldata[p].number != lnumber && alldata[p].profile != lprofile){		
		s=k;
		SetData(data,k);
		k += user;
		GetData(data,alldata,k,s);

		start = clock();

		Similarity(data , mydata);

		end = clock();
		time += (double)(end - start)/CLOCKS_PER_SEC;

		Simil(data , simi);

		printf("%d,near%lf,nearID%d,\n",k,zz,neardata); 
	}
	printf("%lf\n",zz);
	printf("nearID%d\n",neardata);
	printf("end\n");
	printf("time =%lf\n" ,time) ;
	
	free(alldata);
	free(data);
	free(mydata);
	free(s_data);

	return 0;
}

void SetMyData(ratings *mydata)
{
	int j;
	for(j=0;j<id;j++){
		mydata[j].number=1;
		mydata[j].profile=j+1;
		mydata[j].rate=0;
	}
}

void SetData(ratings *data,int k)
{
	int i,j;
	for(i=0;i<user;i++){
		for(j=i*id;j<(i+1)*id;j++){
			data[j].number=i+k+1;
			data[j].profile=(j+1)-i*id;
			data[j].rate=0;

		}
	}
}

void GetData(ratings *data , ratings *alldata ,int k, int s)
{
	int j=0;
	int y,o,m,n;
	for(j=0;alldata[j+p].number<k+1;j++){
		o = alldata[j+p].number;
		m = alldata[j+p].profile;
		n = alldata[j+p].rate;
		y = ((o-s-1)*id)+(m-1);

		data[y].number = o;
		data[y].profile = m;
		data[y].rate = n;
		
		if(alldata[j+p].number == lnumber && alldata[j+p].profile == lprofile){break;}
	}
	p = p+j;
}

void Similarity(ratings *data , ratings *mydata)
{
	int i=0,j=0,r=0;
	double x=0.0,y=0.0,a=0.0;
	for(i=0;i<user;i++){
		x = 0.0;
		if(data[i*id].number >lnumber){
			break;
		}
		for(j=0;j<id;j++){
			s_data[j]=mydata[j].rate-data[i*id+j].rate;
			a=s_data[j];
			x += (a*a);
		}
		simi[i] = 1/(1+x);
	}
}

void Simil(ratings *data , double *simil)
{
	int i=0;
	for(i=0;i<user;i++){
		if(data[i*id].number >lnumber){
			break;
		}
		if(simil[i] > zz){
			neardata = data[i*id].number;
			zz = simil[i];
		}
	}
}