///////////////////////////////////////
//
//	Gleichungssysteme nach Gauss lösen
//
//	26.1.2003, Gerry Brönnimann
//
///////////////////////////////////////



public class Gauss_gb
{

	static int m = 3;	// m: Anzahl Gleichungen
	static int n = 3;	// n: Anzahl Unbekannte

	static double[][] koeff;// = new double[][] { {2,1,-2}, {1,2,2}, {-2,2,-1} }; // Koeffizientenmatrix
	//static double[][] koeff = new double[][] { {4,2,-2}, {1,-4,2}, {-3,1,0} }; // Koeffizientenmatrix
	//static double[][] koeff = new double[][] { {6,2,-1}, {9,1,3.5}, {3,2,4} }; // Koeffizientenmatrix
	static double[]   konst;// = new double[] { 18,9,0 };	// Konstantenmatrix
	static double[]	  loesung;// = new double[n];

	static int[] P;// = new int[] {0,1,2};	// Reihenfolge der Gleichungen


	////////////////////////////////////////
	// main()

 	static public void main(String[] args)
 	{
		int a = 1;
		int b = m;
		int index = 1;
		String[] s;

		out("Gauss'scher Algorithmus\n\nAnzahl Gleichungen:");
		m = InOut.getInt();
		n = m;

		koeff = new double[m][n];
		konst = new double[m];
		loesung = new double[n];
		P = new int[m];
		for (int i=0; i<m; i++)
		{
			P[i] = i;
		}

		koeffizienten();

		out("---------");

		konstanten();

		printLines();

		out("------\n");


		//ordnen();


		for (int i=1; i<m; i++)
		{

			for(int k=i+1; k<m+1; k++)
			{
				addieren(i,k,index);
				printLines();
			}
			index++;
		}


		/*
		addieren(1,2,1);
		printLines();
		addieren(1,3,1);
		printLines();
		addieren(2,3,2);
		printLines();
		*/

		solve();

	}


	////////////////////////////////////////
	// koeffizienten()

	static void koeffizienten()
	{
		boolean exit  = false;
		boolean eingabe = false;
		int l = 0;
		char zeichen;
		Double temp;
		String sKoeff[] = new String[m];
		String sVar[]   = new String[n];
		koeff = new double[m][n];

		for (int i=0; i<n; i++)
		{
			sVar[i] = "";
		}

		// Gleichunszeilen einlesen
		for (int i=0; i<m; i++)
		{
			out(i+1+") "+"Variablen x1 bis x"+n+" eingeben, trennen durch Leerschlaege, ohne Loesung:");

			while(!eingabe)
			{
				sKoeff[i] = InOut.getLine();
				if (sKoeff[i].length() > n-1)
				{
					eingabe = true;
					sKoeff[i] = sKoeff[i] + " ";
				}


				// einzelne Variablen bestimmen
				for(int j=0; l<n && j<sKoeff[i].length(); j++)
				{
					zeichen = sKoeff[i].charAt(j);

					if (zeichen !=' ' && zeichen != '\n')
					{
						sVar[l] = sVar[l] + zeichen;
					}
					else
					{
						//exit = true;
						out(sVar[l]);
						temp = Double.valueOf(sVar[l]);
						koeff[i][l] = temp.doubleValue();
						l++;
					}
					//j=k;
					//l++;
				}
				l = 0;
				for (int c=0; c<n; c++) { sVar[c] = ""; } // Strings löschen

			}
			eingabe = false;
			//l = 0;
			//j = 0;
		}
	}


	////////////////////////////////////////
	// konstanten()

	static void konstanten()
	{
		boolean exit  = false;
		boolean eingabe = false;
		int l = 0;
		char zeichen;
		Double temp;
		String sKonst = new String();
		String sVar[]   = new String[n];

		for (int i=0; i<n; i++)
		{
			sVar[i] = "";
		}

		out("Konstanten 1 bis "+m+" eingeben, trennen durch Leerschlaege:");

		while(!eingabe)
		{
			sKonst = InOut.getLine();
			if (sKonst.length() > m-1)
			{
				eingabe = true;
				sKonst = sKonst + " ";
			}


			// einzelne Variablen bestimmen
			for(int j=0; l<n && j<sKonst.length(); j++)
			{
				zeichen = sKonst.charAt(j);

				if (zeichen !=' ' && zeichen != '\n')
				{
					sVar[l] = sVar[l] + zeichen;
				}
				else
				{
					//exit = true;
					//out(sVar[l]);
					temp = Double.valueOf(sVar[l]);
					konst[l] = temp.doubleValue();
					l++;
				}
				//j=k;
				//l++;
			}
			l = 0;
			for (int c=0; c<m; c++) { sVar[c] = ""; } // Strings löschen

		}
		eingabe = false;
	}


	////////////////////////////////////////
	// addieren()

	static void addieren(int a, int b, int index)
	{
		//double temp;
		double faktor1;
		double faktor2;
		boolean addieren = false;

		index--;

		faktor1 = koeff[b-1][index];
		faktor2 = koeff[a-1][index];

		if(abs(faktor1)==abs(faktor2))	// falls |faktor1| = |faktor2|: +-1
		{
			faktor1 = faktor1/abs(faktor1);
			faktor2 = faktor2/abs(faktor2);
		}

		// Zeilen addieren oder subtrahieren?
		if (faktor1*faktor2 < 0) addieren = true; else addieren = false;


		for(int i=index; i < (int)koeff[b-1].length; i++)
		{
			if (addieren)
			{
				koeff[b-1][i] = abs(faktor1)*koeff[a-1][i]+abs(faktor2)*koeff[b-1][i];	// +
				//out("+");
			}
			else
			{
				koeff[b-1][i] = abs(faktor1)*koeff[a-1][i]-abs(faktor2)*koeff[b-1][i];
				//out("-");
			}
		}

		if (addieren)
		{
			konst[b-1] = abs(faktor1)*konst[a-1]+abs(faktor2)*konst[b-1];
		}
		else
		{
			konst[b-1] = abs(faktor1)*konst[a-1]-abs(faktor2)*konst[b-1];
		}

	}


	////////////////////////////////////////
	// solve()

	static void solve()
	{
		double s;

		double eps = 0;

		String l = "loesung: ";

		out("solve...\n");

		double sum;

		// zuerst letzte Gleichung lösen...
		loesung[m-1] = konst[P[m-1]] / koeff[P[m-1]][m-1];

		// ... dann den Rest
		for (int i = (m-2); i >= 0; i--)
		{
			sum = konst[P[i]];
			for (int j = i; j < m; j++)
			{
				sum = sum - (koeff[P[i]][j] * loesung[j]);
			}
			loesung[i] = sum / koeff[P[i]][i];
			//out(loesung[i]);
		}


		for (int i=0; i<m; i++)
		{
			l = l + loesung[i];
			if (i<m-1) l = l + ", ";
		}
		out("========================================");
		out(l);
		out("========================================");
		out("");


	}


	////////////////////////////////////////
	// printLines()

	static void printLines()
	{
		printLine(0);
		printLine(1);
		printLine(2);
		out("");
	}


	////////////////////////////////////////
	// printLine()

	static void printLine(int line)
	{
		String s = "";

		for (int i=0; i<m; i++)
		{
			s = s + (int)koeff[line][i] + " ";
		}
		s = s + " = " + (int)konst[line];

		System.out.println("line "+line+": " + s);
	}


	////////////////////////////////////////
	// ordnen()

	static void ordnen()
	{
		double[] quersumme = new double[m];
		int[] reihenfolge = new int[m];
		double   temp = 0;
		int exponent =0;

		for (int i=0; i<m; i++)
		{
			for(int k=n-1; k>=0; k--)
			{
				temp = temp + (double)abs( koeff[i][k] )*Math.pow(10,exponent);
				exponent +=2;
			}
			quersumme[i] = temp;
			out(temp);
			exponent = 0;
			temp = 0;

		}
		arraySort(quersumme);
		out(quersumme[0]);
	}

	////////////////////////////////////////
	// abs()

	static double abs(double wert)
	{
		if(wert>=0) return wert;
		else return wert*(-1);
	}


	////////////////////////////////////////
	// arraySort()

	static void arraySort(double[] ar)
	{
		int groesse = ar.length;
		int i=0;
		int k=0;
		double temp;
		int index = groesse-1;

		for (i=0; i<groesse-1; i++)
		{
			for(k=i; k<index; k++)
			{
				if(ar[k] > ar[k+1])
				{
					temp = ar[k+1];
					ar[k] = ar[k+1];
					ar[k+1] = ar[k];
				}
			}
			index--;
		}
	}

	////////////////////////////////////////
	// out()

	static void out(String s)
	{
		System.out.println(s);
	}

	static void out(double s)
	{
		System.out.println(s);
	}

	static void out(int s)
	{
		System.out.println(s);
	}


}