#include <algorithm>
#include <iostream>
#include <limits>
#include <vector>

using namespace std;

bool generate(vector<int>& temp, int& target, const size_t width, const size_t i) {
	const auto replacement = temp[i];
	const auto result = target > replacement;

	if (result) {
		for_each(begin(temp), next(begin(temp), min(temp.size(), i + width - 1)), [=](auto& it) {
			if (target == it) {
				it = replacement;
			} else if (target < it) {
				--it;
			} });
	}
	target = replacement;
	return result;
}

int main() {
	const vector<char> rooms = { 0b1101,	0b110,	0b1101,	0b110,	0b1100,	0b101,	0b110,
	                             0b1110,	0b1001,	0b110,	0b1011,	0b1010,	0b1111,	0b1010,
	                             0b1000,	0b101,	0b11,	0b1110,	0b1011,	0b1110,	0b1010,
	                             0b1011,	0b1101,	0b101,	0b1,	0b101,	0b11,	0b1011 };
	const size_t width = 7U;
	auto result = 0;
	vector<int> temp(rooms.size());

	for (size_t i = 0U; i < rooms.size(); ++i) {
		const auto toWest = (rooms[i] & 0b1000) == 0;
		const auto toNorth = (rooms[i] & 0b100) == 0;
		const auto toEast = (rooms[i] & 0b10) == 0;
		const auto toSouth = (rooms[i] & 0b1) == 0;
		const auto west = toWest && temp[i - 1] != 0 ? temp[i - 1] : numeric_limits<int>::max();
		const auto north = toNorth && temp[i - width] != 0 ? temp[i - width] : numeric_limits<int>::max();
		const auto east = toEast && temp[i + 1] != 0 ? temp[i + 1] : numeric_limits<int>::max();

		temp[i] = min({ temp[i] != 0 ? temp[i] : numeric_limits<int>::max(), result + 1, west, north, east });

		if (temp[i] == result + 1) ++result;

		if (toWest) result -= generate(temp, temp[i - 1], width, i);
		if (toNorth) result -= generate(temp, temp[i - width], width, i);
		if (toEast) result -= generate(temp, temp[i + 1], width, i);
		if (toSouth) temp[i + width] = temp[i];
	}

	for (auto it = cbegin(temp); it != cend(temp);) {
		for (auto i = 0; i < width; ++i, ++it) cout << *it << '\t';
		cout << endl;
	}

	cout << endl << result << endl;
}