// FYLLADIO 5 ASKHSH 12 C++ 2019-2020
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <time.h>
#define N 100
#define M 20
#define m 10
using namespace std;

class test_prime{
private:
	int x;
	int couples[m*2];
	int count;

public:
	//default constructor
	test_prime()
	{x=0; count=0; for (int i=0;i<m*2;i++) couples[i]=0;}

	//constructor with parameters' list
	test_prime(int in_x, int in_couples[], int in_count)
	{
		x=in_x;
		count=in_count;
		if (in_count>0)
			for (int i=0;i<in_count*2;i+=2)
			{
				couples[i]=in_couples[i];
				couples[i+1]=in_couples[i+1];
			};

	};

	int get_x(){return x;};

	void get_couples(int *c) 
		{	for (int i=0;i<m*2;i++)
				c[i]=couples[i];
		};

	int get_count(){return count;};
	
	int get_element(int b)
	{ int counter=0;
		if (count>0)
			for (int i=0;i<count*2;i++)
				if (couples[i]==b) counter++;
		return counter;
	};

	int get_prime(int b) 	{return couples[b];};

void print()
{cout<<x<<"  "<< count<<" couples  :";
if (count>0)
for (int i=0;i<count*2;i+=2)
	cout<<couples[i]<<" "<<couples[i+1]<<" ,  ";
cout<<endl<<endl;
}

}; //end test_prime class definition

int find_prime(int a)
	{	int i;
		bool isPrime = true;

		for (i=2; i<= a/2; i++)
			{
				if (a % i == 0)
					{
						isPrime = false;
						break;
					}
			}
		if (isPrime) return 1;
			else return 0;
	} // end function is_prime

//derived class
class new_test_prime: public test_prime {
private:
	int next_prime;
public:
	new_test_prime(): test_prime()
	{
		 next_prime = 0;
	};
	new_test_prime(int in_x, int *in_couples, int in_count) : test_prime(in_x, in_couples, in_count)
	{
		int flag=0, temp;
		temp=get_x()+1;    // cout<<"temp="<<temp<<endl;
		while (flag==0)
		{ 
			if (find_prime(temp)==1) flag=1;
			else temp++;

		} // end while

		next_prime = temp; 
		//cout<<"next_prime= "<<next_prime<<endl;
	};

	void new_print()
	{print(); cout<<"next_prime= "<<next_prime<<endl<<endl;}
	
}; // end class new_test_prime


int main()
{ int i, z, j, d, in_x, k,u, p[N]={0}, f[N]={0}, in_count, in_couples[m*2], c_array[m*2], c=0, metr=0, flag=0;
test_prime a[M];
new_test_prime g[M];
int *y1, zz=0, average;  

srand((unsigned int)time(0));

// initialize array a
cout<<"INITIALIZE Object array a"<<endl;
for(i=0;i<M;i++) 
{ a[i]=test_prime(); a[i].print();}

ifstream fg;
fg.open("primes.txt");
	if(!fg) {
		cout<<"file does not open"<<endl;
		exit(1);
		}
	k=0;
	 cout<<"----------------------------------------------------"<<endl;
	while(!fg.eof())
	{  // read from file
		fg>>p[k]; k++;
	}; // end while not eof()

	// display numbers from file
	k=k-1;
	if (k>0)
		for (i=0;i<k;i++) cout<<p[i]<<"  ";
	cout<<endl<<endl;

	for (i=0;i<M;i++)
	{
	//create random numbers between 100 - 900, check if not prime
		do
		{
			in_x=rand()%800+100;
			if (find_prime(in_x)==1) { cout<<in_x<<"  is prime!!!!"<<endl;metr++;}
		}
		while (find_prime(in_x));
		c=0;
	// check if in_x is prime or not
	cout<<"RANDOM number ="<<in_x<<endl;
	//finding prime couples
	// c - counter of couples
	for (u=0;u<k-1;u++)
		for (z=u+1;z<k;z++)
		{
			if (p[u]+p[z]==in_x) 
			{ cout<<p[u]<<" "<<p[z]<<endl;
				in_couples[c]=p[u];
				in_couples[c+1]=p[z];
				c=c+2;
			}
		}
		in_count=c/2;

		//EXPLICIT CALL - CONSTRUCTOR WITH PARAMETERS' LIST
		a[i]=test_prime(in_x, in_couples, in_count);
		//a[i].print();

	}; // end for i for M objects
	//ERWTHMA 2
	cout<<"metr="<<metr<<endl;

	//display array of objects
	cout<<"ARRAY OF OBJECTS"<<endl;
	for (i=0;i<M;i++) a[i].print();


	//ERWTHMA 3
	for (d=0;d<k;d++)
		for (i=0;i<M;i++)
			{
				f[d]+=a[i].get_element(p[d]);
		    };
	//display frequencies
	cout<<endl<<"frequencies"<<endl;
	for (j=0;j<k;j++)
		cout<<p[j]<< "  "<<f[j]<<endl;

  // ERWTHMA 4
	// dynamic array
			if (flag==0)  {y1=new int; flag=1;}
			for (i=0;i<M;i++)
			{
				if (a[i].get_count() > 0)
					{ for (j=0;j<a[i].get_count();j+=2)
						{ average=(a[i].get_prime(j)+a[i].get_prime(j+1))/2;
							y1[zz]=a[i].get_x();
							y1[zz+1]=a[i].get_prime(j);
							y1[zz+2]=average;
							zz=zz+3;
						}
					}
			};
			//display dynamic array
			if (zz>0)
				for (d=0;d<zz;d=d+3)
					cout<<"     triplet = "<<y1[d]<<"  "<<y1[d+1]<<"  "<<y1[d+2]<<endl;
		
			//dynamic array end

  // ERWTHMA 5 - inheritance

			//initialize and display derived class
			for (i=0;i<M;i++) g[i]=new_test_prime();
			cout<<endl<<endl<<" class new_test_prime"<<endl;
			//for (i=0;i<M;i++) g[i].print();

			//copy 

			for (i=0;i<M;i++) 
			{			
				a[i].get_couples(c_array);
				
				g[i]=new_test_prime(a[i].get_x(),c_array, a[i].get_count() );
				g[i].new_print();
			}

return 0;
} // end main
