/*

Name: Oliver Neumann (JSmith@gmx.at)
MatrNr.: 0126493
Bsp: 3082

Aufgabenstellung: Einlesen von Auftrittswahrscheinlichkeiten und
                  deren Codewortlaenge; Berechnung und Ausgabe von:
                  
                  - Mittlerer Informationsgehalt des Codes (H)
                  - Redundanz des Codes (R)
                  - relative Redundanz (r)

Anmerkung: Der Code wurde mit dem Proton Editor geschrieben
           und ist unter EMACS womoeglich nicht ordentlich
           formatiert!
                  
*/

import eprog.*;
public class Infge extends EprogIO
{	public static void main (String[] args) throws EprogException
	{	boolean EndeEingabe = false;			// benoetigter Wahrheitswert fuer die Erfassung des Eingabe Endes
		boolean InputError = false;				// benoetigte Fehlermeldungen
		boolean InputError2 = false;
		boolean Ptolarge = false;
		boolean Zeichenfolge = false;
		double h_Array[] = new double[8];		// Array in dem der Informationsgehalt eines Zeichens berechnet und gespeichter wird
		float L_Array[] = new float[8];			// Array für die Wortlänge des Codes
		float P_Array[] = new float[8];			// Array für den Informationsgehalt des Codes
		float PWert;							// Fuer die Berechnung und Pruefwerte benoetigte Variablen
		int lWert = 0;
		int PLaenge = 0;
		int LLaenge = 0;
		int i;
		float PCheckwert = 0;
		float HWert = 0;
		float LWert = 0;
		float RWert = 0;
		float relWert = 0;
		
		try
		{  do								// hier werden die Daten abwechselnd der Reihe nach eingelesen,
			{ PWert = readFloat();			// zuerst der Wahrscheinlichkeitswert (p) dann die Codelaenge (l)
			  if (PWert<0)					// bis zur Eingabe eines negativen Wertes der die Folge abschliesst und
			  	{	EndeEingabe = true;		// die Schleife verlaesst
			  	if (PLaenge==0)
			  		{	InputError = true;
			  		}
				}
				else
				{	if ((PWert>0) && (PWert<=1) && (PLaenge<=8))
			  			{	P_Array[PLaenge]=PWert;									// im Array wird der Wert hinterlaegt
			  				h_Array[PLaenge]=(Math.log(1/PWert))/(Math.log(2));		// und hier berechnet
			  	 		}
			  	 		PLaenge++;
			  	 	 	lWert = readInt();		// einlesen der Codelaenge
			  	 		if (lWert<0)
			  	 		{	EndeEingabe = true;
			  	 		if (LLaenge==0)
			  	 			{	InputError = true;
			  	 			}
			  	 		}
			  	 	else
			  	 	{	if ((lWert>0) && (lWert<=5) && (LLaenge<=8))
			  			{	L_Array[LLaenge]=lWert;				//Speicherung des Wertes im Array fuer die Codelaenge
			  			}
			  			else
			  				{	InputError = true;
			  				}
			  			LLaenge++;
			  		}
			  	}
			} while (!EndeEingabe);
		if (InputError)							// ab hier beginnt die Fehlerbehandlung und der Rechenschritt
		{	println("FALSCHE EINGABE");
			System.exit(0);
		}
		else if ((PLaenge==LLaenge) && (PLaenge>=2) && (PLaenge<=8))	// ist die Zahlenfolge unkorrekt wird
			{	for (i=0; i<P_Array.length; i++)						// und uebersteigen die Summe aller Haeufigkeiten 1
					{	PCheckwert += P_Array[i];						// wird der Rechenvorgang abgebrochen
					}													// und eine Fehlermeldung ausgegeben
					if (PCheckwert!=1.0000000)
						{	Ptolarge = true;
						}
						if (Ptolarge)
							{	println("FALSCHE EINGABE");
								System.exit(0);
							}
							else
								{	for (i=0; i<P_Array.length; i++)		// Kernstueck der Programmes! Hier
									{	HWert += h_Array[i]*P_Array[i];		// werden die ersten Ausgabedaten
									}										// (H), (L) und (R) berechnet
									for (i=0; i<L_Array.length; i++)
									{	LWert += P_Array[i]*L_Array[i];
									}
									RWert = LWert - HWert;
								}
							if (RWert<0)								// ist (R) negativ, wuerde keine
								{	InputError2 = true;					// Berechnung fuer (r) moeglich sein
								}										// daher wird hier eine evt. Fehlerbehandlung
							if (InputError2)							// durchgenommen
								{	println("FALSCHE EINGABE");
									System.exit(0);
								}
								else									// ist alles korrekt werden hier die Werte
									{	relWert = RWert/LWert;			// ausgegeben
							   			printFixed(HWert);print(" ");printFixed(RWert);print(" ");printFixed(relWert);
										println();
									}
			}
		else								// wurde wie oben beschrieben die Zahlenfolgenbedingung nicht
		{	println("FALSCHE EINGABE");		// erfuellt, wird die Meldung FALSCHE EINGABE ausgegeben
			System.exit(0);
		}
		}	catch (EprogException e)		// sollte generell ein falsches Zeichen eingegeben werden
			{	println("?");				// dass eine Berechnung unmoeglich macht wird sie hier mit dem
				System.exit(0);				// catch abgefangen
			}
	}
}