Skip to content

Instantly share code, notes, and snippets.

@GHolk
Last active November 3, 2018 11:19
Show Gist options
  • Save GHolk/17996c6acfb5926e7377ca3c5c986b63 to your computer and use it in GitHub Desktop.
Save GHolk/17996c6acfb5926e7377ca3c5c986b63 to your computer and use it in GitHub Desktop.
determine two point in ascii maze is connect
#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