#include "message.h"
#include <bits/stdc++.h>
using namespace std;
const int SZ = 31;
const int N = 1025;
bool deb = false;
void dbg(vector<int> xx) {
if (!deb) return;
cout << "DEBUG: ";
for (auto x: xx) cout << x << " ";
cout << "\n";
}
void send_message(std::vector<bool> M, std::vector<bool> C) {
vector<bool> m = M;
vector<bool> c = C;
vector<int> safe;
for (int i = 0; i < SZ; i++) {
if (!c[i]) safe.push_back(i);
}
vector<int> d;
int tot = safe.size();
for (int i = 0; i < tot-1; i++) {
d.push_back(safe[i+1] - safe[i]);
}
d.push_back(SZ - safe.back() + safe[0]);
reverse(m.begin(), m.end());
m.push_back(1);
while (m.size() < N) m.push_back(0);
vector<vector<bool>> grid(66, vector<bool>(SZ, 0));
int currD = 0;
for (int j = 0; j < SZ; j++) {
if (c[j]) continue;
for (int i = 0; i < d[currD]-1; i++) {
grid[i][j] = 0;
}
grid[d[currD]-1][j] = 1;
for (int i = d[currD]; i < 66; i++) {
if (!m.empty()) {
grid[i][j] = m.back();
m.pop_back();
}
}
currD++;
}
for (int i = 0; i < 66; i++) {
send_packet(grid[i]);
}
}
int n;
vector<int> get_cycle(vector<int> nxt) {
for (int i = 0; i < n; i++) {
vector<int> currC;
vector<bool> vis(n, false);
currC.push_back(i);
vis[i] = true;
int c = nxt[i];
while (!vis[c]) {
vis[c] = true;
currC.push_back(c);
c = nxt[c];
}
if (c != i || currC.size() != 16) continue;
return currC;
}
assert(false);
return {-1};
}
std::vector<bool> receive_message(std::vector<std::vector<bool>> R) {
vector<vector<bool>> grid = R;
n = grid.size();
vector<int> nxt(n);
for (int j = 0; j < n; j++) {
int tt = 1;
for (int i = 0; i < 66; i++) {
if (grid[i][j]) break;
tt++;
}
nxt[j] = (j + tt) % 31;
}
dbg({0});
dbg(nxt);
vector<int> safe = get_cycle(nxt);
vector<bool> c(n, true);
for (int i = 0; i < (int)safe.size(); i++) {
c[safe[i]] = false;
}
vector<bool> fin;
for (int j = 0; j < n; j++) {
if (c[j]) continue;
vector<bool> curr;
for (int i = 0; i < 66; i++) curr.push_back(grid[i][j]);
reverse(curr.begin(), curr.end());
while (curr.back() == false) curr.pop_back();
curr.pop_back();
while (!curr.empty()) {
fin.push_back(curr.back());
curr.pop_back();
}
}
reverse(fin.begin(), fin.end());
while (fin.back() == false) fin.pop_back();
fin.pop_back();
reverse(fin.begin(), fin.end());
return fin;
}