Last active
November 3, 2018 11:19
-
-
Save GHolk/17996c6acfb5926e7377ca3c5c986b63 to your computer and use it in GitHub Desktop.
determine two point in ascii maze is connect
This file contains 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 <stdlib.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <inttypes.h> | |
#define putsNoLn(string) fputs(string, stdout) | |
#define PRI_cell PRIuFAST8 | |
#define SCN_cell SCNuFAST8 | |
#define PRI_index PRIuFAST8 | |
#define SCN_index SCNuFAST8 | |
enum maze_cell { | |
MAZE_WALL_CELL, | |
MAZE_EMPTY_CELL, | |
MAZE_WALK_CELL | |
}; | |
typedef enum maze_cell maze_cell_t; | |
typedef uint_fast8_t index_t; | |
const uint_fast8_t x = 1; | |
const uint_fast8_t y = 0; | |
struct maze { | |
maze_cell_t **table; | |
index_t height; | |
index_t width; | |
}; | |
typedef struct maze maze; | |
maze_cell_t* maze_index(maze* m, index_t index[2]) { | |
return &m->table[index[y]][index[x]]; | |
} | |
void maze_print_index(index_t index[2]) { | |
printf("(%" PRI_index ",%" PRI_index ")", index[x], index[y]); | |
} | |
void maze_scanf_index(index_t index[2]) { | |
scanf("%" SCN_index " %" SCN_index, &index[x], &index[y]); | |
} | |
uint_fast8_t maze_cell_to_number(maze_cell_t cell) { | |
if (cell == MAZE_EMPTY_CELL) return 0; | |
else return 1; | |
} | |
maze_cell_t maze_cell_from_number(uint_fast8_t number) { | |
if (number == 0) return MAZE_EMPTY_CELL; | |
else return MAZE_WALL_CELL; | |
} | |
void maze_print(maze* m) { | |
for (index_t i=0; i<m->height; i++) { | |
for (index_t j=0; j<m->width; j++) { | |
index_t index[2] = {i, j}; | |
maze_cell_t *cell = maze_index(m, index); | |
printf("%" PRIuFAST8 " ", maze_cell_to_number(*cell)); | |
} | |
putchar('\n'); | |
} | |
} | |
maze* maze_create(index_t height, index_t width) { | |
maze* m = malloc(sizeof(maze)); | |
maze_cell_t* table = calloc(height*width, sizeof(maze_cell_t)); | |
memset(table, MAZE_EMPTY_CELL, sizeof(maze_cell_t)*height*width); | |
maze_cell_t** table_row = calloc(height, sizeof(maze_cell_t*)); | |
for (index_t i=0; i<height; i++) { | |
table_row[i] = &table[i*width]; | |
} | |
m->height = height; | |
m->width = width; | |
m->table = table_row; | |
return m; | |
} | |
maze* maze_copy(maze* m) { | |
maze* copy = maze_create(m->height, m->width); | |
return copy; | |
} | |
void maze_delete(maze* m) { | |
free(m->table[0]); | |
free(m->table); | |
free(m); | |
} | |
void maze_scanf(maze* m) { | |
for (index_t i=0; i<m->height; i++) { | |
for (index_t j=0; j<m->width; j++) { | |
index_t index[2] = {i, j}; | |
maze_cell_t* cell = maze_index(m, index); | |
uint_fast8_t input_number; | |
scanf("%" SCNuFAST8, &input_number); | |
*cell = maze_cell_from_number(input_number); | |
} | |
} | |
} | |
bool maze_is_legal_index(maze* m, index_t index[2]) { | |
if (index[x] < 0 || index[y] < 0) return false; | |
else if (index[x] >= m->width || index[y] >= m->height) return false; | |
else return true; | |
} | |
bool maze_is_connect_recursive(maze* m, maze* walk_map, | |
index_t start[2], index_t end[2]) { | |
putsNoLn("check "); | |
maze_print_index(start); | |
putchar('\n'); | |
if (!maze_is_legal_index(m, start)) { | |
puts("illegal road"); | |
return false; | |
} | |
maze_cell_t* walk_cell = maze_index(walk_map, start); | |
if (*walk_cell == MAZE_WALK_CELL) { | |
puts("redundant road"); | |
return false; | |
} | |
else *walk_cell = MAZE_WALK_CELL; | |
maze_cell_t* current_cell = maze_index(m, start); | |
if (*current_cell != MAZE_EMPTY_CELL) { | |
puts("it is wall"); | |
return false; | |
} | |
if (current_cell == maze_index(m, end)) { | |
puts("find answer"); | |
return true; | |
} | |
index_t other_index[2]; | |
other_index[x] = start[x]; | |
other_index[y] = start[y]; | |
// upper | |
other_index[y]--; | |
if (maze_is_connect_recursive(m, walk_map, other_index, end)) goto answer; | |
// lower | |
other_index[y] += 2; | |
if (maze_is_connect_recursive(m, walk_map, other_index, end)) goto answer; | |
// right | |
other_index[y]--; | |
other_index[x]++; | |
if (maze_is_connect_recursive(m, walk_map, other_index, end)) goto answer; | |
// left | |
other_index[x] -= 2; | |
if (maze_is_connect_recursive(m, walk_map, other_index, end)) goto answer; | |
return false; | |
answer: | |
maze_print_index(other_index); | |
putchar('\n'); | |
return true; | |
} | |
bool maze_is_connect(maze* m, index_t start[2], index_t end[2]) { | |
maze* walk_map = maze_copy(m); | |
bool is_connect = maze_is_connect_recursive(m, walk_map, start, end); | |
maze_delete(walk_map); | |
return is_connect; | |
} | |
int main() { | |
index_t height; | |
index_t width; | |
scanf("%" SCN_index " %" SCN_index, &height, &width); | |
maze* m = maze_create(height, width); | |
maze_scanf(m); | |
puts("maze is:"); | |
maze_print(m); | |
index_t start[2]; | |
index_t end[2]; | |
maze_scanf_index(start); | |
maze_scanf_index(end); | |
putsNoLn("start: "); | |
maze_print_index(start); | |
putchar('\n'); | |
putsNoLn("end: "); | |
maze_print_index(end); | |
putchar('\n'); | |
puts("determine start end connect or not..."); | |
if (maze_is_connect(m, start, end)) puts("connect"); | |
else puts("not connect"); | |
maze_delete(m); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment