import java.io.*;
import java.util.*;
/**
* Klasse mit eigenen Hilfsfunktionen von mr037
* z.B. zur vereinfachten Tastatureingabe
*
* @author mr037
*/
public final class Mylib{
	static final LineNumberReader in = new LineNumberReader (new InputStreamReader (System.in));
	
   /**
    * Zahl von der Tatstatur einlesen
    *
    * @param   text  Text mit dem zur Eingabe aufgefordert wird
    * @return        eingelesene Zahl
    */
	
	public static double zahlLesen(String text){
		while(true){
			System.out.print(text+": ");
			try{return Double.parseDouble(in.readLine());}
			catch (IOException e) {FehlerUndSchluss("IO",e);}
			catch (NumberFormatException e) {System.out.println("Bitte eine Zahl eingeben!");}
		}
	}
	
   /**
    * Zahl von der Tatstatur einlesen und sicherstellen, daß sie zwischen min und max liegt.
    *
    * @param  text  Text mit dem zur Eingabe aufgefordert wird
    * @param  min   kleinster erlaubter Wert
    * @param  max   größter erlaubter Wert
    * @return       eingelesene Zahl
    */
 	public static double zahlLesen(String text, double min, double max){
		double zahl=0.0;
		while(true){
			if((zahl=zahlLesen(text+" ("+min+" ... "+max+")"))>=min && zahl<=max) return zahl;
			else System.out.println("Bitte eine Zahl zwischen "+min+" und "+max+" eingeben!");
		}
	}
	
   /**
    * Programm aufgrund eines schweren Fehlers abbrechen.
    * @param  Fehlerart  Art des Fehlers (z.B. IO)
    * @param  e          Exception, die den Fehler hervorgerufen hat.
    */
     	static void FehlerUndSchluss(String Fehlerart, Exception e){
			System.out.println("************************************");
			System.out.println(Fehlerart + " Fehler: " + e.getMessage());
			System.out.println("************************************");
			e.printStackTrace();
			System.exit(1); // Programm beenden
	}


   /**
    * ganze Zahl von der Tatstatur einlesen
    *
    * @param   text  Text mit dem zur Eingabe aufgefordert wird
    * @return        eingelesene ganzeZahl
    */
	
	public static int ganzeZahlLesen(String text){
		while(true){
			System.out.print(text+": ");
			try{return Integer.parseInt(in.readLine());}
			catch (IOException e) {FehlerUndSchluss("IO",e);}
			catch (NumberFormatException e) {System.out.println("Bitte eine Zahl eingeben!");}
		}
	}
	
	/**
    * ganze Zahl von der Tatstatur einlesen und sicherstellen, daß sie zwischen min und max liegt.
    *
    * @param  text  Text mit dem zur Eingabe aufgefordert wird
    * @param  min   kleinster erlaubter Wert
    * @param  max   größter erlaubter Wert
    * @return       eingelesene ganze Zahl
    */
 	public static int ganzeZahlLesen(String text, int min, int max){
		int zahl=0;
		while(true){
			if((zahl=ganzeZahlLesen(text+" ("+min+" ... "+max+")"))>=min && zahl<=max) return zahl;
			else System.out.println("Bitte eine Zahl zwischen "+min+" und "+max+" eingeben!");
		}
	}
	
	/**
	* Ja-Nein Frage stellen und Antwort von der Tastatur einlesen
	* @param   text Frage
	* @return      Antwort
	*/
	public static boolean jaNein(String text){
		String Antwort = "";
		while(true){
			System.out.print(text+": ");
			try{
				Antwort = in.readLine().trim().toUpperCase();
				if(Antwort.equals("JA")   ||Antwort.equals("J")) return true;
				if(Antwort.equals("NEIN") ||Antwort.equals("N")) return false;
				System.out.println("Bitte mit ja oder nein Antworten!");
			}
			catch (IOException e) {FehlerUndSchluss("IO",e);}
		}
	}
	
	/**
	* in gegebenen int Array Zahlen einlesen
	* @param   text       text mit dem zur Eingabe aufgefordert wird 
	* @param   intArray   Das Array welches mit Zahlen gefuellt werden soll 
	*/
	
	public static void intArrayLesen (String text, int[] ary){
	if (ary.length==0) System.out.println("Fehler! Array ist 0");
	else{
		System.out.println(text);
		System.out.println("Bitte geben Sie jetzt "+ary.length+" Zahlen ein");
		for (int z=0;z<ary.length;z++){
			ary[z]=ganzeZahlLesen("Bitte "+(z+1)+". Zahl eingeben");
		}
		return;
		}
	}
	
	/**
	* Überladene Methode - in gegebenen int Array Zahlen einlesen OHNE Text (a4)
	* @param   intArray   Das Array welches mit Zahlen gefuellt werden soll 
	*/
	
	public static void intArrayLesen (int[] ary){
	if (ary==null) System.out.println("\nFehler! Array ist 0");
	else{
		System.out.println("\nBitte "+ary.length+" Zahlen eingeben");
		for (int z=0;z<ary.length;z++){
			ary[z]=ganzeZahlLesen(""+(z+1)+". Zahl");
		}
		return;
		}
	}
		
	/**
	* Text und Array formatiert ausgeben (a4)
	* @param   text			Ueberschrift
	* @param   intArray 	Das Array welches mit Zahlen gefuellt werden soll 
	*/
	
	public static void intArrayAusgeben (String text, int[] ary){
	int k=0;
	int zaehler=0;
	int indexZaehler=0;
	if (ary==null) System.out.println("\nFehler! Das Array ist leer");
	else{
		System.out.println("\n"+text+" (Laenge "+ary.length+"):\n");
		System.out.println("   |     0|     1|     2|     3|     4|     5|     6|     7|     8|     9|\n--------------------------------------------------------------------------");
		for (int z=0;z<((ary.length/10)+1);z++){
			System.out.print(""+format(indexZaehler, 3)+"|");
			if 	((ary.length-indexZaehler)>=10){
				k=10;
			}
			else k=(ary.length-indexZaehler);
			indexZaehler=(indexZaehler+10);	
			for (int j=0;j<(k);j++) {
				String ausgabeString=format(ary[zaehler], 6);
				System.out.print(""+ausgabeString);
				System.out.print("|");
				zaehler++;
			}
			System.out.print("\n");
		}
	System.out.println(" ");
	}
	}
		
	/**
	* Mittelwert von int Array berechnen 
	* @param   intArray 	Array mit Zahlen deren Mittelwert errechnet werden soll
	*/
	
	public static double mittelwert (int[]ary){
		double summe=0;
		for (int i=0;i<ary.length;i++){
			summe=summe+(double)(ary[i]);
		}
		return summe/ary.length;
		}
		
	/**
	* Mittelwert von double Array berechnen 
	* @param   doubleArray 	Array mit Zahlen deren Mittelwert errechnet werden soll
	*/
	
	public static double mittelwert (double[]ary){
		double summe=0;
		for (int i=0;i<ary.length;i++){
			summe=summe+ary[i];
		}
		return summe/ary.length;
		}
	
	/**
	* Text einlesen - testweise angehaengt fuer a40
	* @param    text 	Text mit dem zur Eingabe aufgefordert wird
	*/
	
	public static String textLesen(String meldung){
		System.out.print(meldung+": ");
		String Zeile=null;
		try{
			Zeile=in.readLine().trim();
		}catch (IOException e) {FehlerUndSchluss("IO",e);}
		return Zeile;
	}

	/**
	* Zahl in String mit fester Laenge formatieren
	* @param    zahl 	Zahl die umgewandelt werden soll
	* @param    len 	Laenge das Strings
	*/
	
		public static String format(int zahl, int len){
		String S=new String(""+zahl);
		int n=len-S.length();
		for (int i=0;i<n;i++) S=" "+S;
		return S;
	}
	
	/**
	* Array mit Zufallszahlen (0...999) fuellen
	* @param    int[]Z 	Array, das mit Zufallszahlen gefuellt werden soll
	*/

		// Dafuer brauchts den "import java.util.*;" am Kopf der Seite
		public static void fillRandomArray(int[]Z){
		if (Z==null) System.out.println("\nFehler: das Array ist leer.\n");
		else{
			Random zufallsZahl= new Random();
			for (int i=0;i<Z.length;i++) Z[i]=zufallsZahl.nextInt(1000);		
			}
		}	

	/**
	* Array mit Zufallszahlen (0...999) der Laenge n erzeugen
	* @param    n 	Laenge des Arrays, das mit Zufallszahlen gefuellt werden soll
	*/
	
		public static int[] makeRandomArray(int n){
		int Z[]=new int[n];
		fillRandomArray(Z);
		return Z;
		}
		
	/**
	* Array nach Maximalwert durchsuchen
	* @param    int[]Z 	Array, in dem das Maximum gesucht werden soll
	*/
	
		static int indexMaximum (int[]Z){
		int maximum=0;
		if (Z==null) System.out.println("\nFehler: das Array ist leer.");
		else{
			maximum=Z[0];
			for (int i=0;i<Z.length;i++){
				if (maximum<Z[i]) maximum=Z[i];
			}
		}
		return maximum;
		}

	/**
	* Array nach Minimalwert durchsuchen
	* @param    int[]Z 	Array, in dem das Minimum gesucht werden soll
	*/
	
		static int indexMinimum (int[]Z){
		int minimum=0;
		if (Z==null) System.out.println("\nFehler: das Array ist leer.");
		else{
			minimum=Z[0];
			for (int i=0;i<Z.length;i++){
				if (minimum>Z[i]) minimum=Z[i];
			}
		}
		return minimum;
		}

	/**
	* Array: Mittelwert bestimmen
	* @param    int[]Z 	Array, aus dessen Werte der Mitelwert gebildet werden soll
	*/
	
		static float mittelWert(int[]Z){
		int summe=0;
		float mittel=0;
		if (Z==null) System.out.println("\nFehler: das Array ist leer.");
		else{
			for (int i=0;i<Z.length;i++){
				summe=summe+Z[i];
			}
			mittel=(((float)(summe))/Z.length);
		}
		return mittel;
		}
		
	/**
	* Array: sortiertes int Array durchsuchen (A11)
	* @param    int[]A 	Array, das durchsucht wird
	* @param    int x 	gesuchter Wert
	*/
	
		static int binSuche(int[]A, int x){
			int unten=0;
			int oben=A.length-1;
			return binRekursiveSuche(A, x, unten, oben);
		}

	/**
	* Array: rekursive Suche nach Wert in int-Array (A11)
	* @param    int[]A 	Array, das durchsucht wird
	* @param    int x 	gesuchter Wert
	* @param    int links 	untere Grenze
	* @param    int rechts 	obere Grenze
	*/
	
		static int binRekursiveSuche(int[]A, int x, int links, int rechts){
			int m=((links+rechts)/2);
			if (A[m]==x) return m;
			else{
				if (links>=rechts) return -1;
					else{
						if ((A[m]>x)) return binRekursiveSuche(A, x, links, m-1);
							else return binRekursiveSuche(A, x, m+1, rechts);
					}
			}
	}

	/**
	* Array: Tausche zwei Werte in einem int-Array (A12)
	* @param    int[]A 	Array, das die Werte enthaelt
	* @param    int i 	erster Wert
	* @param    int j 	zweiter Wert
	*/
	
	public static void tausche(int []A, int i, int j){
		int zwischenSpeicher=A[i];
		A[i]=A[j];
		A[j]=zwischenSpeicher;
	}

}
