Cod sursa(job #1579178)

Utilizator haller.emanuelaEmanuela Haller haller.emanuela Data 24 ianuarie 2016 14:54:57
Problema Algoritmul lui Gauss Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 3.75 kb
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

#define IN_FILENAME 	"./teste/grader_test2.in"

//#define IN_FILENAME 	"gauss.in"
#define OUT_FILENAME	"gauss.out"

#define EPS 		0.0000001

bool readInputData(
	float 		**A,
	int32_t 	*n,
	int32_t		*m)
{
	bool bRes = 0;
	FILE *file;
	
	file = fopen(IN_FILENAME, "r");

	if (file==NULL)
		bRes = 1;

	if (bRes == 0)
	{
		fscanf(file, "%d %d", n, m);

		*A = (float*)malloc((*n) * ((*m)+1) * sizeof(float));

		if (*A == NULL)
			bRes = 1;
	}

	if (bRes == 0)
	{			
		int32_t i;
		float *pA;
		pA = *A;
		for (i=0; i< (*n)*((*m)+1); i++)
			fscanf(file, "%f", pA++);
	}
	
	if (file!=NULL)
		fclose(file);

	return bRes;
}

bool writeOutputData(
	float 		*x,
	int32_t 	m,
	bool 		hasSolution)
{
	bool bRes = 0;
	FILE *file;

	file = fopen(OUT_FILENAME, "w");

	if (file==NULL)
		bRes = 1;

	if (bRes == 0)
	{
		if (hasSolution == true)
		{
			int32_t i;
			float *pX = x;
			for(i=0; i<m; i++)
				fprintf(file, "%15.10f ", *pX++);
			fprintf(file, "\n");
		}
		else
		{
			fprintf(file, "Imposibil\n");
		}
	}

	if (file!=NULL)
		fclose(file);

	return bRes;
}

void displaySystem(
	float 		*A, 
	int32_t 	n,
	int32_t 	m)
{
	int32_t i, j;
	for(i=0; i< n; i++)
	{
		for(j=0; j<m+1; j++)
		{
			printf("%15.10f ", A[i * (m+1) +j]);
		}
		printf("\n");
	}
	printf("\n");
}

bool checkSystem(
	float  		*A,
	float 		*x,
	int32_t 	n,
	int32_t 	m)
{
	bool bRes = true;
	int32_t i, j;
	
	for(i = 0; i < n && bRes == true; i++)
	{
		float val = 0;
		for(j=0; j < m; j++)
		{
			val += A[i * (m+1) + j] * x[j];
		}
		if (abs(val - A[i*(m+1)+m]) > EPS)
			bRes = false;
	} 
	return bRes;
}


bool solve(
	float 		*A,
	int32_t 	n,
	int32_t 	m,
	float 		*x,
	bool 		*hasSolution)
{
	bool bRes = 0;
	
	int32_t i, j;
	
	*hasSolution = true;

	i = j = 0; 

	while (i<n && j < m && (*hasSolution) == true)
	{
		int32_t x = i;

		while (x < n && abs(A[x * (m+1) + j]) <= EPS)
			x++;

		if (x==n)
		{
			/* var j is a free variable */
			j++;
		}	
		else
		{
			int32_t l, u;
			/* line i <-> line x */
			if (x != i)
			{
				for(l=0; l<m+1; l++)
				{
					float aux;
					aux = A[i * (m+1) + l];
					A[i * (m+1) + l] = A[x * (m+1) + l];
					A[x * (m+1) + l] = aux;
				}
			}

			for (l = j+1; l < (m+1); l++)	// elements from 0 to j-1 - already 0
			{
				A[i * (m+1) + l] /= A[i * (m+1) + j];
			}
			A[i * (m+1) + j] = 1;
			
			for (u=i+1; u < n; u++)   
			{
				float val = A[u * (m+1) + j];
				for (l=j; l < (m+1); l++ )   // elements from 0 to j-1 - already 0
					A[u * (m+1) + l] -= (A[i * (m+1) + l] * val);
			}
			j++; 
			i++;
		}
		/*displaySystem(A, n, m);*/
	}
	
	/*displaySystem(A, n, m);*/

	for (i=n-1; i>=0; i--) 
//	for (i = m-1; i >=0; i--)	/* lines were swaped => first m lines will contain the needed info */
	{
		j = 0;
		while (j < m+1 && abs(A[i * (m+1) + j]) <= EPS)
			j++;
		if (j==m)
		{
			*hasSolution = false;
		}
		else if (j<m)
		{
			/* compute variable j */
			int32_t l;
			x[j] = A[i * (m+1) + m];
			for(l = j+1; l < m; l++)
			{
				x[j] -= A[i * (m+1) + l] * x[l];
			} 
			
		}
	}
	

	return bRes;
}


int main()
{
	bool bRes = 0;

	/* n - nEquations, m - nVariables */
	int32_t n, m;
	/* equations matrix */	
	float 	*A = NULL;
	/* variables */
	float 	*x = NULL;
	/* specify if the system has a solution */
	bool hasSolution = true;

	bRes = readInputData(&A, &n, &m);
	
	/*displaySystem(A, n, m);*/

	if (bRes == 0)
	{
		x = (float*)calloc(m, sizeof(float));
		if (x==NULL)
			bRes = 1;
	}
	
	if (bRes == 0)
	{
		bRes = solve(A, n, m, x, &hasSolution);
	}

/*
	if (hasSolution == true)
	{
		bool checks = checkSystem(A, x, n, m);
		if (checks == true)
			printf("check\n");
		else 
			printf("fail\n");
	}
*/
	

	if (bRes == 0)
	{
		writeOutputData(x, m, hasSolution);		
	}
	
	free(A);
	free(x);

	return (int)bRes;
}