Печатные комнаты, но доступ только один раз

Я ковырялся в способе печати номеров из этой проблемы. Я использовал рисование символов расширенный ASCII чтобы проверить это, я понимаю, что это ограничивает область, в которой будет компилироваться мой код.

Краткое объяснение проблемы, если вы не хотите читать там:

Комната определяется как 4-битное целое число, такое что

  • Самый важный бит показывает, есть ли в комнате западная стена
  • Следующий, наиболее важный момент, имеет ли комната северную стену
  • Немаловажно, имеет ли комната восточную стену
  • Наименее значимый бит показывает, имеет ли комната южную стену

Например, комната, представленная 0b1101 будет иметь западную, северную и южную стены:

┌─
│
└─

Есть дополнительные ограничения:

  1. Наружные стены комнат всегда будут иметь стену
  2. Внутренние стены всегда будут выражены в обеих комнатах (пример 0b1101 имеет стену на юг, поэтому в комнате под ней должен быть установлен следующий по значимости бит, указывающий на северную стену)
  3. Там никогда не будет больше, чем numeric_limits<int>::max() номера

Моя проблема — выбор символа пересечения. Мой алгоритм перебора должен иметь доступ к каждой комнате дважды (за исключением комнат в первом ряду / столбце.) Есть ли способ найти пересечения только с одним доступом к памяти на комнату?


Если вы хотите увидеть мой код для справки; это принимает в:

  1. vector<char> информации о комнате
  2. size_t давая ширину ряда
  3. vector<int> с метками для каждой комнаты (это может быть установлено vector(size(testValues), -17) просто напечатать структуру комнаты без меток
string printArray(const vector<char>& testValues, const size_t width, const vector<int>& indexes) {
if (empty(testValues)) {
return string();
} else {
string result;
auto prevLine = "\xC9\xCD"s;

prevLine.reserve(2U * (1U + width));

for (auto i = 0U; i + 1 < width; ++i) {
if ((testValues[i] & 0b10) != 0) {
prevLine += "\xD1\xCD"s;
} else {
prevLine += "\xCD\xCD"s;
}
}
prevLine += "\xBB\n"s;

result.reserve(size(prevLine) * (1U + 2U * size(testValues) / width));

for (auto i = 0U; i < size(testValues) - width; ++i) {
const auto x = i % width;

const auto isBottomSet = (testValues[i] & 0b1) != 0;

if (x == 0) {
result += (prevLine + '\xBA') + static_cast<char>('0' + indexes[i]);
prevLine = isBottomSet ? "\xC7\xC4"s : "\xBA "s;
}

if (x + 1U == width) {
result += "\xBA\n"s;
prevLine += isBottomSet ? "\xB6\n"s : "\xBA\n"s;
} else {
const auto isRightSet = (testValues[i] & 0b10) != 0;
const size_t index = static_cast<int>(isRightSet) << 3 | testValues[i + width + 1] & 0b100 | (testValues[i + width + 1] & 0b1000) >> 2 | static_cast<int>(isBottomSet);
// MSB: isAboveIntersectionSet
//      isRightOfIntersectionSet
//      isBelowIntersectionSet
// LSB: isLeftOfIntersectionSet
constexpr const char* getIntersection[] = { "  ", // 0b0
"  ", // 0b1
"  ", // 0b10
"\xBF ", // 0b11
" \xC4", // 0b100
"\xC4\xC4", // 0b101
"\xDA\xC4", // 0b110
"\xC2\xC4", // 0b111
"  ", // 0b1000:
"\xD9 ", // 0b1001
"\xB3 ", // 0b1010
"\xB4 ", // 0b1011
"\xC0\xC4", // 0b1100
"\xC1\xC4", // 0b1101
"\xC3\xC4", // 0b1110
"\xC5\xC4" }; // 0b1111

result += { isRightSet ? '\xB3' : ' ', static_cast<char>('0' + indexes[i + 1]) };
prevLine += getIntersection[index];
}
}

result += (prevLine + '\xBA') + static_cast<char>('0' + indexes[size(testValues) - width]);
prevLine = "\xC8\xCD"s;

for (auto i = size(testValues) - width; i + 1 < size(testValues); ++i) {
if ((testValues[i] & 0b10) != 0) {
result += { '\xB3', static_cast<char>('0' + indexes[i + 1]) };
prevLine += "\xCF\xCD"s;
} else {
result += { ' ', static_cast<char>('0' + indexes[i + 1]) };
prevLine += "\xCD\xCD"s;
}
}
return result + "\xBA\n"s + prevLine + '\xBC';
}
}

Если вы заинтересованы в простом тесте для этого, вы можете сделать:

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 vector<int> indexes = { 1,    1,  2,  2,  3,  3,  3,
1,    1,  1,  2,  3,  5,  3,
1,    1,  1,  6,  3,  6,  3,
1,    6,  6,  6,  6,  6,  3 };

cout << printArray(rooms, width, indexes) << endl;

Чтобы запустить это, вам нужно перейти к http://webcompiler.cloudapp.net/ и вставьте все в.

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]