#include "stdio.h"
#include "iostream.h"

// писк детерминанта с использванием механизма перестановки строк
double getDeterminant( double **coefficients, int currRowAndColumn, int numberOfEquation ) {
	double result;
	bool allElementsInCurrentColumnEqualsZero = true;
	int i, k, row;
	double tempItem;

	if ( currRowAndColumn == numberOfEquation - 1 ) {
		result = coefficients[currRowAndColumn][currRowAndColumn];
	}
	else {
		// если в текущем столбце все элементы ниже текущей строки равны 0 - детерминант равен 0
		// если элемент на диагонали - нулевой, ищем в текущем столбце ненулевой элемент в строках ниже текущей
		// для перестановки
		for ( i = currRowAndColumn; i < numberOfEquation; i++ ) {
			if ( coefficients[i][currRowAndColumn] != 0 ) {
				allElementsInCurrentColumnEqualsZero = false;
				row = i;
				break;
			}
		}

		if ( allElementsInCurrentColumnEqualsZero ) {
			result = 0.0;
		}
		else {
			// если нужно - переставляем местами строки в матрице
			double normalizingCoef = 1.0;
			if ( row != currRowAndColumn ) {
				normalizingCoef = -1.0;
				for ( i = currRowAndColumn; i < numberOfEquation; i++ ) {
					tempItem = coefficients[currRowAndColumn][i];
					coefficients[currRowAndColumn][i] = coefficients[row][i];
					coefficients[row][i] = tempItem;
				}				
			}

			// преобразуем элементы матрицы для получения диагонального вида
			for ( i = currRowAndColumn + 1; i < numberOfEquation; i++ ) {
				tempItem = -coefficients[i][currRowAndColumn] / coefficients[currRowAndColumn][currRowAndColumn];
				for ( k = currRowAndColumn; k < numberOfEquation; k++ ) {
					coefficients[i][k] = coefficients[i][k] + coefficients[currRowAndColumn][k]*tempItem;
				}
			}

			// рекурсивный вызов с увеличенным счетчиком текущих столбца и строки
			result = coefficients[currRowAndColumn][currRowAndColumn]*normalizingCoef*getDeterminant( coefficients, currRowAndColumn + 1, numberOfEquation );
		}
	}

	return result;
}


void main() {
	int i, j;
	int size;
	double **coefficients;

    cout << "Gauss'es method.\nEnter system dimension: ";
    cin >> size;

	coefficients = new double*[size];
	for ( i = 0; i < size; i++ ) {
		coefficients[i] = new double[size];
	}

	for ( i = 0; i < size; i ++ ){
		cout << "Enter " << i + 1 << " row: ";
		for ( j = 0; j < size; j ++ ){
			cin >> coefficients[i][j];
		}
	}

	cout << "Determinant is: " << getDeterminant( coefficients, 0, size );

    cout << "\nPress \"Enter\" to continue..." << endl; 
    getchar();	
}