//============================================================================
// Name        : Partitions#.cpp
// Author      : Us
// Version     : 1.0
// Copyright   : GNU
// Description : Requests the dimension of the manifold, the number of fixed points, the value of the integral of c_1 c_(n-1) and the index of the manifold; 
//               finds the partitions of the value of c_1 c_(n-1) into 12 nonnegative integers that anihilate the determinant, such that the firs and last elements of the partitions are equal to the index of the manifold.
// Attention   : You should save a copy of this file for each multigraph, substituting # by the number of the multigraph. 
//============================================================================

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <numeric>
#include <cstdlib>
#include <vector>
#include <list>

using namespace std;

static ofstream myfile;

// Attention: Introduce between the parentesis the expression of the determinant associated to the multigraph #

int CalculDet(unsigned short x1,unsigned short x2,unsigned short x3,unsigned short x4,unsigned short x5,unsigned short x6,unsigned short x7,unsigned short x8,unsigned short x9,unsigned short x10,unsigned short x11,unsigned short x12)
{ 
    return (  );
};  // Insert the Determinant above between the parenthesis; 
    
  

bool validSet(unsigned short * firstNum, unsigned short I)
{
	if(	0 == CalculDet(I * firstNum[0],I * firstNum[1],I * firstNum[2],I * firstNum[3],I * firstNum[4],I * firstNum[5],I * firstNum[6],I * firstNum[7],I * firstNum[8],I * firstNum[9],I * firstNum[10],I * firstNum[11]))
	{
		for( int i = 0; i<12; i++) myfile<< I * firstNum[i]<<" ";
		myfile<<endl;
	}
	return true;
};

void part(unsigned short k, unsigned short I, unsigned short m)
{

  // Attention: Partitions with no zeros (we are only considering multigraphs with no self-cycles)
  // Attention: This only considers partitions with first and last element equal to the index of the manifold

	unsigned short r[k];
	int i,j,s;	
	r[0]=1;
	r[k-1]=1;
	r[1]=m-k+1;
        for(i=2;i<k-1;i++){
		r[i]=1;	}
        validSet(r,I);
	while(r[k-2]!=m-k+1){
		i=k-1;
		while(r[--i]==1);
		if(i!=k-2){
			r[i]--;
			r[i+1]=2;
			validSet(r,I);
		}
		else{
			while(r[--i]==1);
			r[i]--;
			s=r[k-2];
			r[k-2]=1;
			r[i+1]=s+1;
			validSet(r,I);
		}
	}
};


int main()
{

  // Requests and stores the dimension of the manifold, the number of fixed points, the value of the integral and the index of the manifold

    int m;
    cout << "Please enter the dimension of the manifold: ";
    cin >> m;
    int N;
    cout << "Please enter the number of fixed points: ";
    cin >> N;
    int z;
    cout << "Please enter the value of the integral of c_1 c_(n-1): ";
    cin >> z;
    int I;
    cout << "Please enter the index of the manifold: ";
    cin >> I;
    
    // Computes the number of elements of each partition (= to the number of edges = to the cardinality of the set I)

    int cardI = N*m/4;

     
     // writes the initial data in the file Data.txt

     cout << "Writing initial data  - dim M,  # fixed points and value of the integral - to the file: Data.txt"<<endl;
     myfile.open ("Data.txt");
     myfile<< m ;
     myfile<< endl;
     myfile<< N;
     myfile<< endl;
     myfile<< z;
     myfile.close();
     cout << "Finished. \n";
     cout << "\n";
    

     // writes the partitions in the file OutputPart#.txt (substitute # by the number of the partition)

     cout << "Writing partitions to the file: OutputPart#.txt"<<endl;
     myfile.open ("OutputPart#.txt");
     part(cardI,I,z/I); // Case with no cycles if there are k cycles then part(cardI-k,I,z/I)
     myfile.close();
     cout << "Finished. \n";
     cout << "\n";

     return 0;
}
