#include "message.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
using namespace std;
vector<bool> send_packet(vector<bool> A);
namespace encode
{
int pos[16];
void send_message(vector<bool> M, vector<bool> C)
{
reverse(M.begin(), M.end());
M.push_back(1);
while (M.size()<1025) M.push_back(0);
reverse(M.begin(), M.end());
M.push_back(0);
assert(M.size()==1026);
//for (bool i:M) cerr<<i; cerr<<endl;
int cnt=0;
for (int i=0; i<31; i++)
{
if (!C[i])
{
pos[cnt++]=i;
}
}
assert(cnt==16);
for (int i=0; i<5; i++)
{
vector<bool> packet(31, ((pos[0]>>i)&1));
send_packet(packet);
}
for (int i=5; i<35; i++)
{
vector<bool> packet(31, 0);
int lft=i*15-76;
for (int j=1; j<16; j++) packet[pos[j]]=M[lft+j];
if (i<pos[0]+5) packet[pos[0]]=C[i-5];
else packet[pos[0]]=C[i-4];
send_packet(packet);
}
for (int i=35; i<71; i++)
{
vector<bool> packet(31, 0);
int lft=i*16-110;
for (int j=0; j<16; j++) packet[pos[j]]=M[lft+j];
send_packet(packet);
}
}
}
void send_message(vector<bool> M, vector<bool> C) { encode::send_message(M, C); }
namespace decode
{
int pos[16];
bool get(vector<bool> packet)
{
int cnt=0;
for (int i=0; i<31; i++) if (packet[i]) cnt++;
if (cnt>=16) return 1;
else return 0;
}
vector<bool> receive_message(vector<vector<bool>> R)
{
assert(R.size()==71);
pos[0]=0;
for (int i=0; i<5; i++)
{
bool z=get(R[i]);
if (z) pos[0]^=(1<<i);
}
int cnt=1;
for (int i=5; i<35; i++)
{
//cerr<<i<<": "<<R[i][pos[0]]<<endl;
if (!R[i][pos[0]])
{
if (i<pos[0]+5) pos[cnt++]=i-5;
else pos[cnt++]=i-4;
}
}
assert(cnt==16);
vector<bool> M;
//for (int i=0; i<cnt; i++) cerr<<pos[i]<<' '; cerr<<endl;
for (int i=5; i<35; i++)
{
for (int j=1; j<16; j++)
{
M.push_back(R[i][pos[j]]);
}
}
for (int i=35; i<71; i++)
{
for (int j=0; j<16; j++)
{
M.push_back(R[i][pos[j]]);
}
}
assert(M.size()==1026);
//for (bool i:M) cerr<<i; cerr<<endl;
M.pop_back();
reverse(M.begin(), M.end());
while (!M.back()) M.pop_back();
M.pop_back();
reverse(M.begin(), M.end());
return M;
}
}
vector<bool> receive_message(vector<vector<bool>> R) { return decode::receive_message(R); }