#include <algorithm>
#include <iostream>
#include <limits>
#include <set>
#include <vector>
using namespace std;
void generate(vector<int>& temp, int& target, const size_t width, const size_t i) {
const auto replacement = temp[i];
if (target > replacement) {
replace(begin(temp), next(begin(temp), min(temp.size(), i + width - 1)), +target, replacement);
} else {
target = replacement;
}
}
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) generate(temp, temp[i - 1], width, i);
if (toNorth) generate(temp, temp[i - width], width, i);
if (toEast) 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 << set<int>(cbegin(temp), cend(temp)).size() << endl;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGltaXRzPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnZvaWQgZ2VuZXJhdGUodmVjdG9yPGludD4mIHRlbXAsIGludCYgdGFyZ2V0LCBjb25zdCBzaXplX3Qgd2lkdGgsIGNvbnN0IHNpemVfdCBpKSB7Cgljb25zdCBhdXRvIHJlcGxhY2VtZW50ID0gdGVtcFtpXTsKCglpZiAodGFyZ2V0ID4gcmVwbGFjZW1lbnQpIHsKCQlyZXBsYWNlKGJlZ2luKHRlbXApLCBuZXh0KGJlZ2luKHRlbXApLCBtaW4odGVtcC5zaXplKCksIGkgKyB3aWR0aCAtIDEpKSwgK3RhcmdldCwgcmVwbGFjZW1lbnQpOwoJfSBlbHNlIHsKCQl0YXJnZXQgPSByZXBsYWNlbWVudDsKCX0KfQoKaW50IG1haW4oKSB7Cgljb25zdCB2ZWN0b3I8Y2hhcj4gcm9vbXMgPSB7IDBiMTEwMSwJMGIxMTAsCTBiMTEwMSwJMGIxMTAsCTBiMTEwMCwJMGIxMDEsCTBiMTEwLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwYjExMTAsCTBiMTAwMSwJMGIxMTAsCTBiMTAxMSwJMGIxMDEwLAkwYjExMTEsCTBiMTAxMCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMGIxMDAwLAkwYjEwMSwJMGIxMSwJMGIxMTEwLAkwYjEwMTEsCTBiMTExMCwJMGIxMDEwLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwYjEwMTEsCTBiMTEwMSwJMGIxMDEsCTBiMSwJMGIxMDEsCTBiMTEsCTBiMTAxMSB9OwoJY29uc3Qgc2l6ZV90IHdpZHRoID0gN1U7CglhdXRvIHJlc3VsdCA9IDA7Cgl2ZWN0b3I8aW50PiB0ZW1wKHJvb21zLnNpemUoKSk7CgoJZm9yIChzaXplX3QgaSA9IDBVOyBpIDwgcm9vbXMuc2l6ZSgpOyArK2kpIHsKCQljb25zdCBhdXRvIHRvV2VzdCA9IChyb29tc1tpXSAmIDBiMTAwMCkgPT0gMDsKCQljb25zdCBhdXRvIHRvTm9ydGggPSAocm9vbXNbaV0gJiAwYjEwMCkgPT0gMDsKCQljb25zdCBhdXRvIHRvRWFzdCA9IChyb29tc1tpXSAmIDBiMTApID09IDA7CgkJY29uc3QgYXV0byB0b1NvdXRoID0gKHJvb21zW2ldICYgMGIxKSA9PSAwOwoJCWNvbnN0IGF1dG8gd2VzdCA9IHRvV2VzdCAmJiB0ZW1wW2kgLSAxXSAhPSAwID8gdGVtcFtpIC0gMV0gOiBudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKCQljb25zdCBhdXRvIG5vcnRoID0gdG9Ob3J0aCAmJiB0ZW1wW2kgLSB3aWR0aF0gIT0gMCA/IHRlbXBbaSAtIHdpZHRoXSA6IG51bWVyaWNfbGltaXRzPGludD46Om1heCgpOwoJCWNvbnN0IGF1dG8gZWFzdCA9IHRvRWFzdCAmJiB0ZW1wW2kgKyAxXSAhPSAwID8gdGVtcFtpICsgMV0gOiBudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKCgkJdGVtcFtpXSA9IG1pbih7IHRlbXBbaV0gIT0gMCA/IHRlbXBbaV0gOiBudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKSwgcmVzdWx0ICsgMSwgd2VzdCwgbm9ydGgsIGVhc3QgfSk7CgoJCWlmICh0ZW1wW2ldID09IHJlc3VsdCArIDEpICsrcmVzdWx0OwoKCQlpZiAodG9XZXN0KSBnZW5lcmF0ZSh0ZW1wLCB0ZW1wW2kgLSAxXSwgd2lkdGgsIGkpOwoJCWlmICh0b05vcnRoKSBnZW5lcmF0ZSh0ZW1wLCB0ZW1wW2kgLSB3aWR0aF0sIHdpZHRoLCBpKTsKCQlpZiAodG9FYXN0KSBnZW5lcmF0ZSh0ZW1wLCB0ZW1wW2kgKyAxXSwgd2lkdGgsIGkpOwoJCWlmICh0b1NvdXRoKSB0ZW1wW2kgKyB3aWR0aF0gPSB0ZW1wW2ldOwoJfQoKCWZvciAoYXV0byBpdCA9IGNiZWdpbih0ZW1wKTsgaXQgIT0gY2VuZCh0ZW1wKTspIHsKCQlmb3IgKGF1dG8gaSA9IDA7IGkgPCB3aWR0aDsgKytpLCArK2l0KSBjb3V0IDw8ICppdCA8PCAnXHQnOwoJCWNvdXQgPDwgZW5kbDsKCX0KCgljb3V0IDw8IGVuZGwgPDwgc2V0PGludD4oY2JlZ2luKHRlbXApLCBjZW5kKHRlbXApKS5zaXplKCkgPDwgZW5kbDsKfQ==