#include "message.h"
#include <cassert>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
std::vector<bool> send_packet(std::vector<bool> A);
vector<bool >full(int val)
{
vector<bool>rez;
for(int i=0; i<31; i++)
{
rez.push_back(val);
}
return rez;
}
vector<bool> enc(vector<int>msg,vector<int>biti)
{
vector<bool>rez;
for(int i=0; i<31; i++)
{
rez.push_back(0);
}
for(int i=0; i<biti.size(); i++)
{
rez[biti[i]]=msg[i];
}
return rez;
}
vector<bool> endcodedim(vector<int>biti,int dim)
{
vector<bool>rez;
for(int i=0; i<31; i++)
{
rez.push_back(0);
}
for(int i=0;i<biti.size();i++)
{
rez[biti[i]]=dim%2;
dim=dim/2;
}
return rez;
}
void send_message(std::vector<bool> M, std::vector<bool> C)
{
int poz=0,p1=-1,p2=-1,i;
for(i=0; i<31; i++)
{
if(C[i]==0 && p1==-1)
{
p1=i;
}
else if(C[i]==0 && p2==-1)
{
p2=i;
}
}
poz=0;
vector<int>first2;
while(1)
{
if(poz+2<p1)
{
first2.push_back(0);
first2.push_back(0);
poz=poz+3;
}
else if(p1==poz)
{
first2.push_back(0);
first2.push_back(1);
break;
}
else if(p1==poz+1)
{
first2.push_back(1);
first2.push_back(0);
break;
}
else
{
first2.push_back(1);
first2.push_back(1);
break;
}
}
poz=p1+1;
while(1)
{
if(poz+2<=p2)
{
first2.push_back(0);
first2.push_back(0);
poz=poz+3;
}
else if(p2==poz)
{
first2.push_back(0);
first2.push_back(1);
break;
}
else if(p2==poz+1)
{
first2.push_back(1);
first2.push_back(0);
break;
}
else
{
first2.push_back(1);
first2.push_back(1);
break;
}
}
for(int i=0; i<first2.size(); i++)
{
send_packet(full(first2[i]));
}
vector<int>biti;
biti.push_back(p1);
biti.push_back(p2);
poz=p2+1;
while(poz<31)
{
vector<int>encode;
encode.clear();
for(int i=0; i<biti.size(); i++)
{
if(i+poz>=31)
encode.push_back(1);
else
encode.push_back(C[i+poz]);
}
send_packet(enc(encode,biti));
for(int i=0; i<encode.size(); i++)
{
if(i+poz<31 && C[i+poz]==0)
{
biti.push_back(i+poz);
}
}
poz=poz+encode.size();
}
send_packet(endcodedim(biti,M.size()));
for(int poz=0; poz<M.size(); poz+=16)
{
vector<int>encode;
encode.clear();
for(int i=0; i<16; i++)
{
if(poz+i>M.size())
{
encode.push_back(0);
}
else
{
encode.push_back(M[poz+i]);
}
}
send_packet(enc(encode,biti));
}
}
int maj(vector<bool> vec)
{
int fre0=0,fre1=0;
for(int i=0;i<vec.size();i++)
{
if(vec[i]==0)
{
fre0++;
}
else
{
fre1++;
}
}
if(fre1>=16)
{
return 1;
}
return 0;
}
vector<bool> decode(vector<bool>rez ,vector<int>biti)
{
vector<bool>rasp;
for(int i=0;i<biti.size();i++)
{
rasp.push_back(rez[biti[i]]);
}
return rasp;
}
int decodesiez(vector<bool>msg ,vector<int>biti)
{
int dim=0,pw=1;
for(int i=0;i<biti.size();i++)
{
if(msg[biti[i]]==1)
{
dim=dim+pw;
}
pw=pw*2;
}
return dim;
}
std::vector<bool> receive_message(std::vector<std::vector<bool>> R)
{
int p1=0,p2=0,b1,b2,poz=0,i=0;
for(i=0; i<R.size(); i+=2)
{
b1=maj(R[i]);
b2=maj(R[i+1]);
if(b1==0 && b2==0)
{
poz=poz+3;
}
else if(b1==0 && b2==1)
{
p1=poz;
break;
}
else if(b1==1 && b2==0)
{
p1=poz+1;
break;
}
else if(b1==1 && b2==1)
{
p1=poz+2;
break;
}
}
i+=2;
poz=p1+1;
for(i ;i<R.size(); i+=2)
{
b1=maj(R[i]);
b2=maj(R[i+1]);
if(b1==0 && b2==0)
{
poz=poz+3;
}
else if(b1==0 && b2==1)
{
p2=poz;
break;
}
else if(b1==1 && b2==0)
{
p2=poz+1;
break;
}
else if(b1==1 && b2==1)
{
p2=poz+2;
break;
}
}
vector<int>biti;
biti.push_back(p1);
biti.push_back(p2);
poz=p2+1;
i+=2;
//cout<<p1<<" "<<p2<<'\n';
while(poz<31)
{
vector<bool>decodare;
decodare=decode(R[i],biti);
for(int i=0;i<decodare.size();i++)
{
if(decodare[i]==0)
{
biti.push_back(i+poz);
}
}
poz=poz+decodare.size();
i++;
}
int sz=decodesiez(R[i],biti);
vector<bool>rasp;
i++;
while(i<R.size())
{
vector<bool>decodeare=decode(R[i],biti);
for(auto x:decodeare)
{
rasp.push_back(x);
}
i++;
}
while(rasp.size()>sz)
{
rasp.pop_back();
}
return rasp;
}