#include "transmission.h"

#include <iostream>
const int MAX_M = 100000;

static std::vector<bool> data;

std::vector<bool> receive_1(const std::vector<bool>& message, int n, int d) {
#ifdef STJO
	std::cout << "received:" << std::endl;
	for(auto x : message) std::cout << x;
	std::cout << std::endl;
#endif

	const int coef = 3;

    data.resize(n, 0);

	int idx = 0;
	for(int i = 0;i < n;i ++) {
		const bool b0 = message[idx + 0];
		const bool b1 = message[idx + 1];
		const bool b2 = message[idx + 2];
#ifdef STJO
		std::cout << "idx=" << idx << std::endl;
#endif
		if(b0 != b1 or b0 != b2 or b1 != b2) {
			idx --;
		}
		if(b0 + b1 + b2 >= 2) data[i] = 1;
		idx += coef;
	}
#ifdef STJO
	std::cout << "final:" << std::endl;
	for(auto x : data) std::cout << x;
	std::cout << std::endl;
#endif

    return data;
}

static int padLen[MAX_M];
std::vector<bool> receive_2(const std::vector<bool>& message, int N, int d) {
#ifdef STJO
	std::cout << "====================================" << std::endl;
	std::cout << "received:" << std::endl;
	for(auto x : message) std::cout << x;
	std::cout << std::endl;
#endif

	const int blockSize = 25;
	const int padSize = 15;
	const int maxD = 2;
	std::vector<int> pads;

	int padBegin = -1;
	bool padType = -1;

	bool last = message[0];
	int streak = 1;

	for(int i = 1;i < message.size();i ++) {
		if(message[i] == last) {
			streak ++;
			if(streak == padSize) {
				pads.push_back(i - streak + 1);
				padLen[i - streak + 1] = streak;
				streak = 1;
			}
		} else {
			if(streak >= padSize - maxD) {
				pads.push_back(i - streak + 1);
				padLen[i - streak + 1] = streak;
			}
			last = message[i];
			streak = 1;
		}
	}
#ifdef STJO
		std::cout << "meta " << pads.size() << std::endl;
		for(auto p : pads) std::cout << p << ' ';
		std::cout << std::endl;
#endif

	data.resize(N);

	int idx = 0;
	int last_ = 0;
	int blockCnt = 0;
	for(int i = 0;i < N;i ++) {
		data[i] = message[idx ++];
		if(padLen[idx] != 0) {
#ifdef STJO
			for(;last_ < idx;last_ ++) std::cout << message[last_];
			std::cout << std::endl;
			//std::cout << "j=" << padLen[idx] << ' ' << "idx=" << idx << std::endl;
#endif
			idx += padLen[idx];
			//std::cout << "idx=" << idx << std::endl;
			//std::cout << "---" << std::endl;
			last_ = idx;
			blockCnt ++;
			i = blockCnt * blockSize - 1;
		}
	}

#ifdef STJO
	std::cout << "totalBlocks:" << blockCnt << std::endl;
	std::cout << "final:" << std::endl;
	for(auto x : data) std::cout << x;
	std::cout << std::endl;
#endif

    return data;
}

std::vector<bool> receive(const std::vector<bool>& message, int n, int d) {
    return receive_2(message, n, d);
}
