Last active
August 18, 2017 20:24
-
-
Save fesoliveira014/6bcf914fda658f469d488349069a4e70 to your computer and use it in GitHub Desktop.
Substance problem
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <malloc.h> | |
#define MAX_SIZE 500 | |
#define MIN_SIZE 10 | |
#define MAX_SUBS 300 | |
struct list_t | |
{ | |
int nodes[MAX_SUBS]; | |
int size; | |
}; | |
void list_push(int i, struct list_t* list) | |
{ | |
if (list->size < MAX_SUBS) { | |
list->nodes[list->size] = i; | |
list->size++; | |
} | |
} | |
int list_has_element(int value, struct list_t* list) | |
{ | |
for (int i = 0; i < list->size; ++i) { | |
if (list->nodes[i] == value) return 1; | |
} | |
return 0; | |
} | |
void clear_list(struct list_t* list) | |
{ | |
for (int i = 0; i < MAX_SUBS; ++i) { | |
list->nodes[i] = 0; | |
} | |
list->size = 0; | |
} | |
int abs(int a) | |
{ | |
return a > 0 ? a : -a; | |
} | |
struct substance_t | |
{ | |
int type; | |
int x0, y0; | |
int x1, y1; | |
}; | |
int board[MAX_SIZE][MAX_SIZE]; | |
int processing_order[MAX_SUBS]; // processing order of a given substance | |
struct list_t dependency_list[MAX_SUBS]; | |
struct substance_t geometries[MAX_SUBS]; // substance position | |
int board_size, max_substance; | |
int target; | |
void find_substance_geometry(struct substance_t* substance) | |
{ | |
int c0_x, c0_y; // upper left | |
int c1_x, c1_y; // upper right | |
int c2_x, c2_y; // lower left | |
int c3_x, c3_y; // lower right | |
c0_x = substance->x0; | |
c0_y = substance->y0; | |
c1_x = c0_x; | |
c1_y = c0_y; // same y-coordinate | |
c2_x = c0_x; // same x-coordinate | |
c2_y = c0_y; | |
c3_x = c0_x; | |
c3_y = c0_y; | |
for (int i = c0_x; i < MAX_SIZE; ++i) { | |
if (board[c1_y][i] == 0) break; | |
if (board[c1_y][i] == substance->type) c1_x = i; | |
} | |
for (int i = c0_y; i < MAX_SIZE; ++i) { | |
if (board[i][c2_x] == 0) break; | |
if (board[i][c2_x] == substance->type) c2_y = i; | |
} | |
if (c1_x != c0_x && c2_y != c0_y) { // there is a 4th corner | |
c3_x = c1_x; | |
c3_y = c2_y; | |
} | |
else if (c1_x != c0_x) { // horizontal strip or bottom left not found | |
c3_x = c1_x; | |
c3_y = c1_y; | |
for (int i = c1_y; i < MAX_SIZE; ++i) { | |
if (board[i][c3_x] == 0) break; | |
if (board[i][c3_x] == substance->type) c3_y = i; | |
} | |
} | |
else if (c2_y != c0_y) { // vertical strip or top right not found | |
c3_x = c2_x; | |
c3_y = c2_y; | |
for (int i = c2_x; i < MAX_SIZE; ++i) { | |
if (board[c3_y][i] == 0) break; | |
if (board[c3_y][i] == substance->type) c3_x = i; | |
} | |
} | |
substance->x1 = c3_x; | |
substance->y1 = c3_y; | |
} | |
int depends(struct substance_t* a, struct substance_t* b) | |
{ | |
if (a->x0 < b->x0 && | |
a->y0 < b->y0 && | |
a->x1 > b->x1 && | |
a->y1 > b->y1) { | |
return 1; // b inside a | |
} | |
else if (abs(a->x0 - b->x0) * 2 < ((a->x1 - a->x0) + (b->x1 - b->x0)) && | |
abs(a->y0 - b->y0) * 2 < ((a->y1 - a->y0) + (b->y1 - b->y0))) { | |
// boxes are intersecting, need to walk on border to infer dependency | |
// if while we are walking on the border of 'a' we find a patch with type 'b' | |
// we can garantee that 'b' depends on 'a' | |
for (int i = a->x0; i <= a->x1; ++i) { // top border walk | |
if (board[a->y0][i] == b->type) return 1; | |
} | |
for (int i = a->y0; i <= a->y1; ++i) { // left border walk | |
if (board[i][a->x0] == b->type) return 1; | |
} | |
for (int i = a->x0; i <= a->x1; ++i) { // bottom border walk | |
if (board[a->y1][i] == b->type) return 1; | |
} | |
for (int i = a->y0; i <= a->y1; ++i) { // right border walk | |
if (board[i][a->x1] == b->type) return 1; | |
} | |
} | |
return 0; | |
} | |
int solve() | |
{ | |
for (int i = 0; i < MAX_SIZE; ++i) { | |
for (int j = 0; j < MAX_SIZE; ++j) { | |
if (board[i][j] != 0 && geometries[board[i][j]].type == 0) { | |
geometries[board[i][j]].type == board[i][j]; | |
geometries[board[i][j]].x0 = j; | |
geometries[board[i][j]].y0 = i; | |
find_substance_geometry(&geometries[board[i][j]]); | |
} | |
} | |
} | |
for (int i = 0; i < MAX_SUBS; ++i) { | |
if (geometries[i].type == 0) continue; | |
for (int j = 0; j < MAX_SUBS; ++j) { | |
if (i == j || geometries[j].type == 0) continue; | |
else if (depends(&geometries[i], &geometries[j]) && !list_has_element(i, &dependency_list[j])) { | |
list_push(i, &dependency_list[j]); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment