fork download
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. class Rooms
  6. {
  7. public:
  8. // variables
  9. int xs, ys; // map resolution
  10. int **map; // map[xs][ys]
  11.  
  12. enum
  13. {
  14. _W = 8,
  15. _N = 4,
  16. _E = 2,
  17. _S = 1
  18. };
  19.  
  20. // internals
  21. Rooms() { map = NULL; xs = 0; ys = 0; }
  22. ~Rooms() { _free(); }
  23. // release map memory
  24. void _free()
  25. {
  26. if (map)
  27. {
  28. for (int x = 0; x<xs; x++)
  29. if (map[x])
  30. delete[] map[x];
  31. delete[] map;
  32. }
  33. map = NULL; xs = 0; ys = 0;
  34. }
  35.  
  36.  
  37. // inteface
  38. // realloc map to new resolution
  39. void resize(int _xs, int _ys)
  40. {
  41. if ((xs == _xs) && (ys == _ys)) return;
  42. _free();
  43. xs = _xs; ys = _ys;
  44. map = new int*[xs];
  45. for (int x = 0; x<xs; x++)
  46. map[x] = new int[ys];
  47. }
  48.  
  49. // count rooms
  50. int count()
  51. {
  52. int x, y, i, i0, i1, w0, w1, n, e;
  53. // each block is a separate room
  54. for (n = 0, x = 0; x<xs; x++)
  55. for (y = 0; y<ys; y++, n += 16)
  56. {
  57. map[x][y] &= 0x0000000F; // low 4 bits are walls
  58. map[x][y] |= n & 0xFFFFFFF0; // rest is room index
  59. } n >>= 4;
  60. // reindex all indexes i0 to i1
  61. #define map_reindex(i0,i1) \
  62.   for (x=0;x<xs;x++) \
  63.   for (y=0;y<ys;y++) \
  64.   if (int(map[x][y]&0xFFFFFFF0)==i0) \
  65.   { \
  66.   map[x][y]&= 0x0000000F; \
  67.   map[x][y]|=i1&0xFFFFFFF0; \
  68.   }
  69. // loop until no change has occured
  70. for (e = 1; e;)
  71. {
  72. e = 0;
  73. // merge columns
  74. for (x = 0; x<xs; x++)
  75. for (y = 1; y<ys; y++)
  76. {
  77. w0 = map[x][y - 1] & 0x0000000F;
  78. i0 = map[x][y - 1] & 0xFFFFFFF0;
  79. w1 = map[x][y] & 0x0000000F;
  80. i1 = map[x][y] & 0xFFFFFFF0;
  81. if ((i0 != i1) && (int(w0&_S) == 0) && (int(w1&_N) == 0)) { map_reindex(i0, i1); n--; e = 1; }
  82. }
  83. // merge rows
  84. for (y = 0; y<ys; y++)
  85. for (x = 1; x<xs; x++)
  86. {
  87. w0 = map[x - 1][y] & 0x0000000F;
  88. i0 = map[x - 1][y] & 0xFFFFFFF0;
  89. w1 = map[x][y] & 0x0000000F;
  90. i1 = map[x][y] & 0xFFFFFFF0;
  91. if ((i0 != i1) && (int(w0&_E) == 0) && (int(w1&_W) == 0)) { map_reindex(i0, i1); n--; e = 1; }
  92. }
  93. }
  94.  
  95. return n;
  96. #undef map_reindex
  97. }
  98. };
  99.  
  100. int main() {
  101. const vector<char> rooms = { 0b1101, 0b0110, 0b1101, 0b0110, 0b1100, 0b0101, 0b0110,
  102. 0b1110, 0b1001, 0b0110, 0b1011, 0b1010, 0b1111, 0b1010,
  103. 0b1000, 0b0101, 0b0011, 0b1110, 0b1011, 0b1110, 0b1010,
  104. 0b1011, 0b1101, 0b0101, 0b0001, 0b0101, 0b0011, 0b1011 };
  105. const size_t width = 7U;
  106. Rooms test;
  107.  
  108. test.resize(width, rooms.size() / width);
  109. for (auto y = 0; y < test.ys; ++y) {
  110. for (auto x = 0; x < test.xs; ++x) {
  111. test.map[x][y] = rooms[x + y * width];
  112. }
  113. }
  114.  
  115. cout << test.count() << endl;
  116. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
5