#include <fstream>
#include <iostream>
#include <utility>
#include <cctype>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include "huffman.h"
using namespace std;
typedef	pair<unsigned char,long> mypair;
typedef pair<unsigned char,string> outpair;

tree* make_tree(const vector<mypair>& vm)
{	
	tree *t1,*t2,*t;t1=new tree();t2=new tree();
	vector<mypair>::const_iterator i;
	priority_queue<tree*,vector<tree*>,comp_tree> treeQueue;
	for(i=vm.begin();i<vm.end();i++)
	{
		tree *mid=new tree((*i).first,(*i).second);
		treeQueue.push(mid);
	}
	while(treeQueue.size()>1)
	{
		t1=treeQueue.top();
		treeQueue.pop();
		t2=treeQueue.top();
		treeQueue.pop();
		t =new tree(t1,t2);
		treeQueue.push(t);
	}
        tree* result=treeQueue.top();
	treeQueue.pop();
	return result;
}

void make_code(tree* t,string code,vector<outpair>& b)
{
	if(t->left==0||t->right==0)
	{
		if(code.size()==0)b.push_back(outpair(t->data,"0"));
                else           
		b.push_back(outpair(t->data,code));
		return;
	}
	else 
	{
		string left=code;left.append("0");
		string right=code;right.append("1");
		make_code(t->left,left,b);
		make_code(t->right,right,b);
	}
}

int main(int n,char* fname[])
{
        vector<mypair> a;
	vector<mypair>::iterator i;
	vector<outpair> b;
	vector<outpair>::iterator j;
	bool added;
	a.clear();b.clear();
	if(n!=2)return 1;
	ifstream is(fname[1]);

	unsigned char s;
	while(!is.eof())
	{
		is.get(s);
		added=false;
		for(i=a.begin();i<a.end();i++)
		{
			if((*i).first==s){(*i).second++;added=true;}
		}
		if(!added)a.push_back(mypair(s,1));
	}
	tree* huffman=make_tree(a);
	string str;
	make_code(huffman,str,b);

	for(unsigned char c=0;c<255;c++)
	{
		for(j=b.begin();j<b.end();j++)
		{if((*j).first==c)/////////////////c has a code
                {

			if(isprint(c)&&c!=' ')cout<<c<<"     "<<j->second<<endl;
		        else
			{ 
				if (int(c)<16)str="0";else str="";
				cout<<"0x"<<str<<hex<<int(c)<<"  "<<j->second<<endl;
			}
		}
		}
	}
	cout<<endl;
	return 0;
}

