int main()
{	
	char** ppchReactants = NULL;
	int iReactantCounter = 0;
	
	SMatrix* qElementEquations = CreateMatrix( 0, 0 );
	char** ppchElementNames = NULL;
	int iElementCounter = 0;
	
	SMatrix* qMatrixB = CreateMatrix( 0, 0 );
	
	int iChangePoint;
	int iCount = 0;
	
	char* pchInput;
	pchInput = (char*)malloc( sizeof( char ) * 64 );
	memset( pchInput, ' ', 64 );
	printf( "Please enter the reactants one at a time.\nPlease use () to denote subscript.\nH(2)O for example. When finished enter '>'.\n\n" );
	
	int iMult = 1;
	
	while( 1 )
	{
		if( iMult == 1 )
		{
			printf( "Enter reactant:\n" );
		}
		else
		{
			printf( "Enter product:\n" );
		}
		scanf( "%s", pchInput );
		
		if( pchInput[0] == '>' )
		{
			if( iMult == 1 )
			{
				iChangePoint = iCount;
				iMult = -1;
				memset( pchInput, ' ', 64 );
				continue;
			}
			else
			{
				break;
			}
		}
		
		++iCount;
		
		int iLength = 0;
		while( pchInput[iLength] != ' ' )
		{
			++iLength;
		}
		pchInput[iLength-1] = '\0';
		
		++iReactantCounter;
		ppchReactants = (char**)realloc( ppchReactants, sizeof( char* ) * iReactantCounter );
		ppchReactants[iReactantCounter-1] = (char*)malloc( sizeof( char ) * iLength );
		memcpy( ppchReactants[iReactantCounter-1], pchInput, iLength );
		
		int iPass = 0;
		for( int i = 0; i < (iLength-1); ++i )
		{
			int iIncrement = 0;
			if( ( pchInput[i] >= 65 ) && ( pchInput[i] <= 90 ) )
			{
				if( ( pchInput[i+1] >= 97 ) && ( pchInput[i+1] <= 122 ) )
				{
					char* pchName = (char*)malloc( sizeof( char ) * 3 );
					pchName[0] = pchInput[i];
					pchName[1] = pchInput[i+1];
					pchName[2] = '\0';
					iIncrement += 1;
					
					int iAmount = 1;
					
					if( ( pchInput[i+2] == '(' ) && ( ( pchInput[i+3] >= 48 ) && ( pchInput[i+3] <= 57 ) )  )
					{
						iIncrement += 1;
						char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 );
						for( int j = 3; j <= 10; ++j )
						{
							iIncrement += 1;
							if( pchInput[i+j] == ')' )
							{
								break;
							}
							chNumberBuffer[j-3] = pchInput[i+j];
						}
						iAmount = atoi( chNumberBuffer );
						free( chNumberBuffer );
					}
					
					int iPlace = -1;
					for( int j = 0; j < iElementCounter; ++j )
					{
						if( !strcmp( pchName, ppchElementNames[j] ) )
						{
							iPlace = j;
						}
					}
					
					if( iPlace == -1 )
					{
						++iElementCounter;
						ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter );
						ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * 3 );
						memcpy( ppchElementNames[iElementCounter-1], pchName, 3 );
						
						qElementEquations->m_iRows = iElementCounter;
						qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double * ) * iElementCounter );
						if( !iPass )
						{
							for( int j = 0; j < iElementCounter; ++j )
							{
								qElementEquations->m_iColumns = iReactantCounter;
								qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
								qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
							}
						}
						else
						{
							qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter );
						}
						memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) );
						qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount );
					}
					else
					{
						if( !iPass )
						{
							for( int j = 0; j < iElementCounter; ++j )
							{
								qElementEquations->m_iColumns = iReactantCounter;
								qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
								qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
							}
						}
						qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount );
					}
					
					free( pchName );
				}
				else
				{
					char* pchName = (char*)malloc( sizeof( char ) * 2 );
					pchName[0] = pchInput[i];
					pchName[1] = '\0';
					
					int iAmount = 1;
					
					if( ( pchInput[i+1] == '(' ) && ( ( pchInput[i+2] >= 48 ) && ( pchInput[i+2] <= 57 ) ) )
					{
						iIncrement += 1;
						char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 );
						for( int j = 2; j <= 9; ++j )
						{
							iIncrement += 1;
							if( pchInput[i+j] == ')' )
							{
								break;
							}
							chNumberBuffer[j-2] = pchInput[i+j];
						}
						iAmount = atoi( chNumberBuffer );
						free( chNumberBuffer );
					}
					
					int iPlace = -1;
					for( int j = 0; j < iElementCounter; ++j )
					{
						if( !strcmp( pchName, ppchElementNames[j] ) )
						{
							iPlace = j;
						}
					}
					
					if( iPlace == -1 )
					{
						++iElementCounter;
						ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter );
						ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * 2 );
						memcpy( ppchElementNames[iElementCounter-1],pchName, 2 );
						
						qElementEquations->m_iRows = iElementCounter;
						qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double* ) * iElementCounter );
						if( !iPass )
						{
							for( int j = 0; j < iElementCounter; ++j )
							{
								qElementEquations->m_iColumns = iReactantCounter;
								qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
								qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
							}
						}
						else
						{
							qElementEquations->m_iColumns = iReactantCounter;
							qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter );
						}
						memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) );
						qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount );
					}
					else
					{
						if( !iPass )
						{
							for( int j = 0; j < iElementCounter; ++j )
							{
								qElementEquations->m_iColumns = iReactantCounter;
								qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
								qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
							}
						}
						qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount );
					}
					
					free( pchName );
				}
			}
			if( pchInput[i] == '(' )
			{
				int iCompoundLength = 1;
				int iParenCounter = 0;
				
				for( int j = 0; j < 64; ++j )
				{
					++iCompoundLength;
					if( pchInput[i+j] == '(' )
					{
						++iParenCounter;
					}
					
					if( pchInput[i+j] == ')' )
					{
						--iParenCounter;
					}
					
					if( iParenCounter == 0 )
					{
						break;
					}
				}
				
				iIncrement += ( iCompoundLength - 2 );
				
				char* pchName = (char*)malloc( sizeof( char ) * iCompoundLength );
				for( int j = 0; j < ( iCompoundLength ); ++j )
				{
					pchName[j] = pchInput[i+j];
				}
				pchName[iCompoundLength-1] = '\0';
				
				int iAmount = 1;
				
				if( ( pchInput[i+iCompoundLength-1] == '(' ) && ( ( pchInput[i+iCompoundLength] >= 48 ) && ( pchInput[i+iCompoundLength] <= 57 ) ) )
				{
					++iIncrement;
					char* chNumberBuffer = (char*)malloc( sizeof( char ) * 10 );
					for( int j = 0; j <= 9; ++j )
					{
						++iIncrement;
						if( pchInput[i+iCompoundLength+j] == ')' )
						{
							break;
						}
						chNumberBuffer[j] = pchInput[i+iCompoundLength+j];
					}
					iAmount = atoi( chNumberBuffer );
					free( chNumberBuffer );
				}
					
				int iPlace = -1;
				for( int j = 0; j < iElementCounter; ++j )
				{
					if( !strcmp( pchName, ppchElementNames[j] ) )
					{
						iPlace = j;
					}
				}

				if( iPlace == -1 )
				{
					++iElementCounter;
					ppchElementNames = (char**)realloc( ppchElementNames, sizeof( char* ) * iElementCounter );
					ppchElementNames[iElementCounter-1] = (char*)malloc( sizeof( char ) * iCompoundLength );
					memcpy( ppchElementNames[iElementCounter-1], pchName, iCompoundLength );
					
					qElementEquations->m_iRows = iElementCounter;
					qElementEquations->m_ppdMatrix = (double**)realloc( qElementEquations->m_ppdMatrix, sizeof( double* ) * iElementCounter );
					if( !iPass )
					{
						for( int j = 0; j < iElementCounter; ++j )
						{
							qElementEquations->m_iColumns = iReactantCounter;
							qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
							qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
						}
					}
					else
					{
						qElementEquations->m_iColumns = iReactantCounter;
						qElementEquations->m_ppdMatrix[iElementCounter-1] = (double*)malloc( sizeof( double ) * iReactantCounter );
					}
					memset( qElementEquations->m_ppdMatrix[iElementCounter-1], 0, sizeof( double ) * ( iReactantCounter - 1 ) );
					qElementEquations->m_ppdMatrix[iElementCounter-1][iReactantCounter-1] = ( iMult * iAmount );
				}
				else
				{
					if( !iPass )
					{
						for( int j = 0; j < iElementCounter; ++j )
						{
							qElementEquations->m_iColumns = iReactantCounter;
							qElementEquations->m_ppdMatrix[j] = (double*)realloc( qElementEquations->m_ppdMatrix[j], sizeof( double ) * iReactantCounter );
							qElementEquations->m_ppdMatrix[j][iReactantCounter-1] = 0;
						}
					}
					qElementEquations->m_ppdMatrix[iPlace][iReactantCounter-1] = ( iMult * iAmount );
				}
				
				free( pchName );
			}
			i+=iIncrement;
			++iPass;
		}
		memset( pchInput, ' ', 64 );
	}
	
	free( pchInput );
	
	qMatrixB->m_iRows = iElementCounter;
	qMatrixB->m_iColumns = 1;
	qMatrixB->m_ppdMatrix = (double**)malloc( sizeof( double* ) * iElementCounter );
	for( int i = 0; i < iElementCounter; ++i )
	{
		qMatrixB->m_ppdMatrix[i] = (double*)malloc( sizeof( double ) * 1 );
		qMatrixB->m_ppdMatrix[i][0] = fabs( qElementEquations->m_ppdMatrix[i][iReactantCounter-1] );
		qElementEquations->m_ppdMatrix[i] = (double*)realloc( qElementEquations->m_ppdMatrix[i], sizeof( double ) * ( iReactantCounter - 1 ) );
	}
	--iReactantCounter;
	--qElementEquations->m_iColumns;
	
	/*
	printf( "\nElement Equation Matrix:\n" );
	for( int i = 0; i < iElementCounter; ++i )
	{
		printf( "%s [", ppchElementNames[i] );
		for( int j = 0; j < ( iReactantCounter + 1 ); ++j )
		{
			if( j == iReactantCounter )
			{
				printf( " = %6.2f ", qMatrixB->m_ppdMatrix[i][0] );
				continue;
			}
			printf( " %6.2f ", qElementEquations->m_ppdMatrix[i][j] );
		}
		printf( "]\n" );
	}
	*/
	
	SMatrix* qMatrixA = SquareMatrix( qElementEquations );
	
	/*
	printf( "\nMatrix A:\n" );
	for( int i = 0; i < qMatrixA->m_iRows; ++i )
	{
		for( int j = 0; j < qMatrixA->m_iRows; ++j )
		{
			printf( "%6.2f", qMatrixA->m_ppdMatrix[i][j] );
		}
		printf( "\n" );
	}
	*/
	
	/*
	printf( "\nMatrix B:\n" );
	for( int i = 0; i < iElementCounter; ++i )
	{
		printf( "%6.2f\n", qMatrixB->m_ppdMatrix[i][0] ); 
	}
	*/
	
	SMatrix* qMatrixAInverse = GetInverseMatrix( qMatrixA );
	
	/*
	printf( "\nMatrix A Inverse:\n" );
	for( int i = 0; i < qMatrixAInverse->m_iRows; ++i )
	{
		for( int j = 0; j < qMatrixAInverse->m_iRows; ++j )
		{
			printf( "%6.2f", qMatrixAInverse->m_ppdMatrix[i][j] );
		}
		printf( "\n" );
	}
	*/
	
	double dDet = (double)DeterminantOfMatrix( qMatrixA );
	
	SMatrix* qFirstMatrix = MultiplyMatrixes( qMatrixAInverse, qMatrixB );
	
	/*
	printf( "\nMatrix A^-1 * Matrix B:\n" );
	for( int i = 0; i < qFirstMatrix->m_iRows; ++i )
	{
		printf( "%6.2f\n", 	qFirstMatrix->m_ppdMatrix[i][0] );
	}
	*/
	
	/*
	printf( "\nDeterminant of Matrix A: %.0f\n", fDet );
	*/

	MultiplyByConstant( qFirstMatrix, dDet );
	
	int iGCDArray[100];
	for( int i = 0; i < ( iReactantCounter + 1 ); ++i )
	{
		if( i != ( iReactantCounter ) )
		{
			iGCDArray[i] = qFirstMatrix->m_ppdMatrix[i][0];
		}
		else
		{
			iGCDArray[i] = dDet;
		}
	}
	
	int iGCD = GreatestCommonDenominatorArray( iGCDArray, ( iReactantCounter + 1 ) );
	
	/*
	printf( "\n( Matrix A^-1 * Matrix B ) * det( Matrix A ):\n" );
	for( int i = 0; i < iSquare; ++i )
	{
		printf( "%6.2f\n", ppdFirstMatrix[i][0] );
	}
	*/
	
	printf( "\nYour final solution is:\n" );
	int iFirst = 1;
	for( int i = 0; i < iChangePoint; ++i )
	{
		if( iFirst )
		{
			printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) );
			printf( "%s", ppchReactants[i] );
			iFirst = 0;
		}
		else
		{
			printf( " + " );
			printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) );
			printf( "%s", ppchReactants[i] );
		}
	}
	printf( " -> " );
	iFirst = 1;
	for( int i = iChangePoint; i < (iReactantCounter+1); ++i )
	{
		if( i != ( iReactantCounter ) )
		{
			if( iFirst )
			{
				printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) );
				printf( "%s", ppchReactants[i] );
				iFirst = 0;
			}
			else
			{
				printf( " + " );
				printf( "%.0f", fabs( qFirstMatrix->m_ppdMatrix[i][0] / iGCD ) );
				printf( "%s", ppchReactants[i] );
			}
		}
		else
		{
			if( iFirst )
			{
				printf( "%.0f", fabs( dDet / iGCD ) );
				printf( "%s", ppchReactants[i] );
			}
			else
			{
				printf( " + " );
				printf( "%.0f", fabs( dDet / iGCD ) );
				printf( "%s", ppchReactants[i] );
			}
		}
	}
	
	FreeMatrix( qElementEquations );
	FreeMatrix( qMatrixB );
	FreeMatrix( qMatrixA );
	FreeMatrix( qMatrixAInverse );
	FreeMatrix( qFirstMatrix );
	
	// ppchElementNames
	for( int i = 0; i < iElementCounter; ++i )
	{
		free( ppchElementNames[i] );
	}
	free( ppchElementNames );
	
	//Free ppchReactants
	for( int i = 0; i < ( iReactantCounter + 1 ); ++i )
	{
		free( ppchReactants[i] );
	}
	free( ppchReactants );
	
	return 0;
}
Exemple #2
0
Vector2f Drawable::TransformToLocal(const Vector2f& point) const
{
    return GetInverseMatrix().Transform(point);
}