//主要感悟:
//建哈夫曼树使用优先队列能够显著减少代码量,也比较容易实现。
//建立一个哈希表,每个字符与一个数字对应,这样编程比较方便
#include <iostream>
#include <queue>
#include <stdio.h>
#include <string.h>
#include <iomanip>
using namespace std;
struct Tree
{
int parent;
int weight;
int order;
int code_lenth;
} a[ 100 ];
struct cmp {
bool operator ()( Tree & a, Tree & b) {
return a. weight> b. weight;
}
} ;
int hash[ 200 ];
int main ()
{
priority_queue< Tree, vector< Tree>, cmp > q;
string n;
while ( getline ( cin, n), n!= "END" )
{
int lenth= n. size ();
int j= 1 ;
memset ( hash, 0 , sizeof ( hash));
a[ 1 ]. order= j;
a[ 1 ]. weight= 1 ;
hash[ n[ 0 ]]= j;
for ( int i= 1 ; i< lenth; i++)
{
int k= hash[ n[ i]];
if ( k)
a[ k]. weight++;
else
{
a[++ j]. weight= 1 ; a[ j]. order= j; hash[ n[ i]]= j;
}
}
for ( int i= 1 ; i<= j; i++)
q. push ( a[ i]);
for ( int i= j+1 ; i<= 2 * j-1 ; i++)
{
Tree temp;
Tree temp1;
Tree temp2;
temp1= q. top ();
q. pop ();
temp2= q. top ();
q. pop ();
a[ temp1. order]. parent= i;
a[ temp2. order]. parent= i;
temp. weight= temp1. weight+ temp2. weight;
temp. order= i;
temp. parent= 0 ;
a[ i]= temp;
q. push ( temp);
}
q. pop ();
for ( int i= 1 ; i<= j; i++)
{
int sum= 0 ;
int k= i;
while ( a[ k]. parent)
{
sum++;
k= a[ k]. parent;
}
a[ i]. code_lenth= sum;
}
int sum_lenth= 0 ;
for ( int i= 0 ; i< lenth; i++)
{
int k= hash[ n[ i]];
sum_lenth+= a[ k]. code_lenth;
}
if ( j== 1 )
sum_lenth= lenth;
cout<< lenth* 8 << " " << sum_lenth<< " " ;
cout<< fixed<< setprecision ( 1 )<<( float ) lenth* 8 /( float ) sum_lenth<< endl;
}
return 0 ;
}