#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#define SEED 0xDEADBEEFull
#define ROWS 100
#define COLS 100
#define COLORS_NUM 3
#define VEC_INIT_CAPACITY 15
#define MATRIX_AT(matrix, i, j) (matrix)[(i) * COLS + (j)]
uint32_t LCGRand()
{
static uint64_t seed = SEED;
seed = seed * 6364136223846793005 + 1442695040888963407;
return seed >> 32;
}
typedef struct Node_s {
uint32_t color;
uint32_t isVisited;
} Node;
typedef struct Coords_s {
intptr_t i;
intptr_t j;
} Coords;
typedef struct Vec_s {
Coords *arr;
size_t curSize;
size_t curCapacity;
} Vec;
Vec *vec_create()
{
Vec
*vec
= calloc(1, sizeof(Vec
)); if (!vec) {
return NULL;
}
vec
->arr
= calloc(VEC_INIT_CAPACITY
, sizeof(Coords
)); if (!vec->arr) {
return NULL;
}
vec->curCapacity = VEC_INIT_CAPACITY;
vec->curSize = 0;
return vec;
}
int vec_push(Vec *vec, intptr_t i, intptr_t j)
{
if (vec->curSize >= vec->curCapacity) {
size_t newCapacity = vec->curCapacity * 2;
Coords *oldArr = vec->arr;
vec
->arr
= realloc(vec
->arr
, newCapacity
* sizeof(Coords
)); if (!vec->arr) {
vec->arr = oldArr;
return 0;
}
vec->curCapacity = newCapacity;
}
vec->arr[vec->curSize].i = i;
vec->arr[vec->curSize].j = j;
vec->curSize++;
return 1;
}
Coords *vec_pop(Vec *vec)
{
if (vec->curSize > 0) {
return &vec->arr[vec->curSize-- - 1];
} else {
return NULL;
}
}
void vec_clear(Vec *vec)
{
vec->curSize = 0;
}
void vec_delete(Vec *vec)
{
if (vec) {
if (vec->arr) {
}
}
}
inline int isValidCoords(intptr_t i, intptr_t j)
{
return (i >= 0) && (i < ROWS) && (j >= 0) && (j < COLS);
}
size_t visitNode(Node *matrix, intptr_t i, intptr_t j)
{
static const int MOVES[][2] = {
{ -1, 0 },
{ +1, 0 },
{ 0, -1 },
{ 0, +1 },
};
Vec *vec = vec_create();
if (!vec) {
goto OOM;
}
if (!vec_push(vec, i, j)) {
goto OOM;
}
size_t blockSize = 0;
uint32_t targetColor = MATRIX_AT(matrix, i, j).color;
MATRIX_AT(matrix, i, j).isVisited = 1;
while (vec->curSize > 0) {
Coords *coords = vec_pop(vec);
i = coords->i;
j = coords->j;
blockSize++;
for (size_t moveIdx = 0; moveIdx < sizeof(MOVES) / sizeof(MOVES[0]); moveIdx++) {
intptr_t movedI = i + MOVES[moveIdx][0], movedJ = j + MOVES[moveIdx][1];
if (isValidCoords(movedI, movedJ)) {
Node *adjNode = &MATRIX_AT(matrix, movedI, movedJ);
if (adjNode->color == targetColor && !adjNode->isVisited) {
MATRIX_AT(matrix, movedI, movedJ).isVisited = 1;
if (!vec_push(vec, movedI, movedJ)) {
goto OOM;
}
}
}
}
}
vec_delete(vec);
return blockSize;
OOM:
vec_delete(vec);
}
void print_matrix(Node *matrix)
{
for (size_t i = 0; i < ROWS; i++) {
for (size_t j = 0; j < COLS; j++) {
putchar(MATRIX_AT
(matrix
, i
, j
).
color + '0'); }
}
}
int main()
{
Node
*matrix
= calloc(ROWS
* COLS
, sizeof(Node
)); for (size_t i = 0; i < ROWS * COLS; i++) {
matrix[i].color = LCGRand() % COLORS_NUM;
}
//print_matrix(matrix);
size_t maxAdjNodes = 0;
for (intptr_t i = 0; i < ROWS; i++) {
for (intptr_t j = 0; j < COLS; j++) {
if (!MATRIX_AT(matrix, i, j).isVisited) {
size_t adjNodes = visitNode(matrix, i, j);
if (maxAdjNodes < adjNodes) {
maxAdjNodes = adjNodes;
}
}
}
}
printf("Max block size: %zd\n", maxAdjNodes
); return 0;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGludC5oPgoKI2RlZmluZSBTRUVEIDB4REVBREJFRUZ1bGwKI2RlZmluZSBST1dTIDEwMAojZGVmaW5lIENPTFMgMTAwCiNkZWZpbmUgQ09MT1JTX05VTSAzCgojZGVmaW5lIFZFQ19JTklUX0NBUEFDSVRZIDE1CiNkZWZpbmUgTUFUUklYX0FUKG1hdHJpeCwgaSwgaikgKG1hdHJpeClbKGkpICogQ09MUyArIChqKV0KCnVpbnQzMl90IExDR1JhbmQoKQp7CiAgICBzdGF0aWMgdWludDY0X3Qgc2VlZCA9IFNFRUQ7CiAgICBzZWVkID0gc2VlZCAqIDYzNjQxMzYyMjM4NDY3OTMwMDUgKyAxNDQyNjk1MDQwODg4OTYzNDA3OwogICAgcmV0dXJuIHNlZWQgPj4gMzI7Cn0KCnR5cGVkZWYgc3RydWN0IE5vZGVfcyB7CiAgICB1aW50MzJfdCBjb2xvcjsKICAgIHVpbnQzMl90IGlzVmlzaXRlZDsKfSBOb2RlOwoKdHlwZWRlZiBzdHJ1Y3QgQ29vcmRzX3MgewogICAgaW50cHRyX3QgaTsKICAgIGludHB0cl90IGo7Cn0gQ29vcmRzOwoKdHlwZWRlZiBzdHJ1Y3QgVmVjX3MgewogICAgQ29vcmRzICphcnI7CiAgICBzaXplX3QgY3VyU2l6ZTsKICAgIHNpemVfdCBjdXJDYXBhY2l0eTsKfSBWZWM7CgpWZWMgKnZlY19jcmVhdGUoKQp7CiAgICBWZWMgKnZlYyA9IGNhbGxvYygxLCBzaXplb2YoVmVjKSk7CiAgICBpZiAoIXZlYykgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgdmVjLT5hcnIgPSBjYWxsb2MoVkVDX0lOSVRfQ0FQQUNJVFksIHNpemVvZihDb29yZHMpKTsKICAgIGlmICghdmVjLT5hcnIpIHsKICAgICAgICBmcmVlKHZlYyk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB2ZWMtPmN1ckNhcGFjaXR5ID0gVkVDX0lOSVRfQ0FQQUNJVFk7CiAgICB2ZWMtPmN1clNpemUgPSAwOwogICAgcmV0dXJuIHZlYzsKfQoKaW50IHZlY19wdXNoKFZlYyAqdmVjLCBpbnRwdHJfdCBpLCBpbnRwdHJfdCBqKQp7CiAgICBpZiAodmVjLT5jdXJTaXplID49IHZlYy0+Y3VyQ2FwYWNpdHkpIHsKICAgICAgICBzaXplX3QgbmV3Q2FwYWNpdHkgPSB2ZWMtPmN1ckNhcGFjaXR5ICogMjsKICAgICAgICBDb29yZHMgKm9sZEFyciA9IHZlYy0+YXJyOwogICAgICAgIHZlYy0+YXJyID0gcmVhbGxvYyh2ZWMtPmFyciwgbmV3Q2FwYWNpdHkgKiBzaXplb2YoQ29vcmRzKSk7CiAgICAgICAgaWYgKCF2ZWMtPmFycikgewogICAgICAgICAgICB2ZWMtPmFyciA9IG9sZEFycjsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgICAgIHZlYy0+Y3VyQ2FwYWNpdHkgPSBuZXdDYXBhY2l0eTsKICAgIH0KCiAgICB2ZWMtPmFyclt2ZWMtPmN1clNpemVdLmkgPSBpOwogICAgdmVjLT5hcnJbdmVjLT5jdXJTaXplXS5qID0gajsKICAgIHZlYy0+Y3VyU2l6ZSsrOwogICAgcmV0dXJuIDE7Cn0KCkNvb3JkcyAqdmVjX3BvcChWZWMgKnZlYykKewogICAgaWYgKHZlYy0+Y3VyU2l6ZSA+IDApIHsKICAgICAgICByZXR1cm4gJnZlYy0+YXJyW3ZlYy0+Y3VyU2l6ZS0tIC0gMV07CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQp9Cgp2b2lkIHZlY19jbGVhcihWZWMgKnZlYykKewogICAgdmVjLT5jdXJTaXplID0gMDsKfQoKdm9pZCB2ZWNfZGVsZXRlKFZlYyAqdmVjKQp7CiAgICBpZiAodmVjKSB7CiAgICAgICAgaWYgKHZlYy0+YXJyKSB7CiAgICAgICAgICAgIGZyZWUodmVjLT5hcnIpOwogICAgICAgIH0KICAgICAgICBmcmVlKHZlYyk7CiAgICB9Cn0KCmlubGluZSBpbnQgaXNWYWxpZENvb3JkcyhpbnRwdHJfdCBpLCBpbnRwdHJfdCBqKQp7CiAgICByZXR1cm4gKGkgPj0gMCkgJiYgKGkgPCBST1dTKSAmJiAoaiA+PSAwKSAmJiAoaiA8IENPTFMpOwp9CgpzaXplX3QgdmlzaXROb2RlKE5vZGUgKm1hdHJpeCwgaW50cHRyX3QgaSwgaW50cHRyX3QgaikKewogICAgc3RhdGljIGNvbnN0IGludCBNT1ZFU1tdWzJdID0gewogICAgICAgIHsgLTEsIDAgfSwKICAgICAgICB7ICsxLCAwIH0sCiAgICAgICAgeyAwLCAtMSB9LAogICAgICAgIHsgMCwgKzEgfSwKICAgIH07CgogICAgVmVjICp2ZWMgPSB2ZWNfY3JlYXRlKCk7CiAgICBpZiAoIXZlYykgewogICAgICAgIGdvdG8gT09NOwogICAgfQoKICAgIGlmICghdmVjX3B1c2godmVjLCBpLCBqKSkgewogICAgICAgIGdvdG8gT09NOwogICAgfQoKICAgIHNpemVfdCBibG9ja1NpemUgPSAwOwogICAgdWludDMyX3QgdGFyZ2V0Q29sb3IgPSBNQVRSSVhfQVQobWF0cml4LCBpLCBqKS5jb2xvcjsKICAgIE1BVFJJWF9BVChtYXRyaXgsIGksIGopLmlzVmlzaXRlZCA9IDE7CiAgICB3aGlsZSAodmVjLT5jdXJTaXplID4gMCkgewogICAgICAgIENvb3JkcyAqY29vcmRzID0gdmVjX3BvcCh2ZWMpOwogICAgICAgIGkgPSBjb29yZHMtPmk7CiAgICAgICAgaiA9IGNvb3Jkcy0+ajsKCiAgICAgICAgYmxvY2tTaXplKys7CgogICAgICAgIGZvciAoc2l6ZV90IG1vdmVJZHggPSAwOyBtb3ZlSWR4IDwgc2l6ZW9mKE1PVkVTKSAvIHNpemVvZihNT1ZFU1swXSk7IG1vdmVJZHgrKykgewogICAgICAgICAgICBpbnRwdHJfdCBtb3ZlZEkgPSBpICsgTU9WRVNbbW92ZUlkeF1bMF0sIG1vdmVkSiA9IGogKyBNT1ZFU1ttb3ZlSWR4XVsxXTsKICAgICAgICAgICAgaWYgKGlzVmFsaWRDb29yZHMobW92ZWRJLCBtb3ZlZEopKSB7CiAgICAgICAgICAgICAgICBOb2RlICphZGpOb2RlID0gJk1BVFJJWF9BVChtYXRyaXgsIG1vdmVkSSwgbW92ZWRKKTsKICAgICAgICAgICAgICAgIGlmIChhZGpOb2RlLT5jb2xvciA9PSB0YXJnZXRDb2xvciAmJiAhYWRqTm9kZS0+aXNWaXNpdGVkKSB7CiAgICAgICAgICAgICAgICAgICAgTUFUUklYX0FUKG1hdHJpeCwgbW92ZWRJLCBtb3ZlZEopLmlzVmlzaXRlZCA9IDE7CiAgICAgICAgICAgICAgICAgICAgaWYgKCF2ZWNfcHVzaCh2ZWMsIG1vdmVkSSwgbW92ZWRKKSkgewogICAgICAgICAgICAgICAgICAgICAgICBnb3RvIE9PTTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgdmVjX2RlbGV0ZSh2ZWMpOwogICAgcmV0dXJuIGJsb2NrU2l6ZTsKCk9PTToKICAgIHBlcnJvcigiT09NIik7CiAgICB2ZWNfZGVsZXRlKHZlYyk7CiAgICBleGl0KEVYSVRfRkFJTFVSRSk7Cn0KCnZvaWQgcHJpbnRfbWF0cml4KE5vZGUgKm1hdHJpeCkKewogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBST1dTOyBpKyspIHsKICAgICAgICBmb3IgKHNpemVfdCBqID0gMDsgaiA8IENPTFM7IGorKykgewogICAgICAgICAgICBwdXRjaGFyKE1BVFJJWF9BVChtYXRyaXgsIGksIGopLmNvbG9yICsgJzAnKTsKICAgICAgICB9CiAgICAgICAgcHV0Y2hhcignXG4nKTsKICAgIH0KfQoKaW50IG1haW4oKQp7CiAgICBOb2RlICptYXRyaXggPSBjYWxsb2MoUk9XUyAqIENPTFMsIHNpemVvZihOb2RlKSk7CiAgICBmb3IgKHNpemVfdCBpID0gMDsgaSA8IFJPV1MgKiBDT0xTOyBpKyspIHsKICAgICAgICBtYXRyaXhbaV0uY29sb3IgPSBMQ0dSYW5kKCkgJSBDT0xPUlNfTlVNOwogICAgfQogICAgLy9wcmludF9tYXRyaXgobWF0cml4KTsKCiAgICBzaXplX3QgbWF4QWRqTm9kZXMgPSAwOwogICAgZm9yIChpbnRwdHJfdCBpID0gMDsgaSA8IFJPV1M7IGkrKykgewogICAgICAgIGZvciAoaW50cHRyX3QgaiA9IDA7IGogPCBDT0xTOyBqKyspIHsKICAgICAgICAgICAgaWYgKCFNQVRSSVhfQVQobWF0cml4LCBpLCBqKS5pc1Zpc2l0ZWQpIHsKICAgICAgICAgICAgICAgIHNpemVfdCBhZGpOb2RlcyA9IHZpc2l0Tm9kZShtYXRyaXgsIGksIGopOwogICAgICAgICAgICAgICAgaWYgKG1heEFkak5vZGVzIDwgYWRqTm9kZXMpIHsKICAgICAgICAgICAgICAgICAgICBtYXhBZGpOb2RlcyA9IGFkak5vZGVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHByaW50ZigiTWF4IGJsb2NrIHNpemU6ICV6ZFxuIiwgbWF4QWRqTm9kZXMpOwogICAgcmV0dXJuIDA7Cn0K