summaryrefslogtreecommitdiff
path: root/graph.h
blob: 6a748ae1fa3a60dd41c3f9aadcef634d33101f3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
typedef struct {
	int	width;
	int	height;
	char**	e;
	bool**	visited;
} Graph2D;

enum {
	NORTH = 0, EAST, SOUTH, WEST, DIRECTIONS,
};

typedef struct {
	int	x;
	int	y;
} Coordinates;

bool
graph_valid(Graph2D* g, Coordinates c)
{
	return c.x >= 0 && c.x < g->width && c.y >= 0 && c.y < g->height;
}

/* Reads from the input until exhausted. Returns memory which must be
freed by the caller. */
Graph2D*
graph_ingest(FILE* in)
{
	char *t = getall(in);
	char *s = t;

	/* Two passes. One to count width and height.
		Another to store to allocated memory. */
	int height = 0, width = -1, i = 0;
	while (s[i] != '\0') {
		if (s[i] == '\n') {
			if (width == -1) {
				width = i + 1; 
			}
			height++;
		}
		i++;
	}
	char** buffer = calloc(height, sizeof(char*));
	bool** visited = calloc(height, sizeof(bool*));

	Graph2D* g = calloc(1, sizeof(Graph2D));
	g->width = width;
	g->height = height;
	g->e = buffer;
	g->visited = visited;
	i = height;
	while (i > 0) {
		buffer[i-1] = calloc(width, sizeof(char));
		visited[i-1] = calloc(width, sizeof(bool));
		i--;
	}

	i = 0;
	int j = 0;
	while (i < height) {
		if (j < width - 1) {
			buffer[i][j] = *s;
			j++;
		} else {
			i++;
			j = 0;
		}
		s++;
	}
	
	free(t);
	return g;
}

void
graph_free(Graph2D* g)
{
	for (int i = 0; i < g->height; i++) {
		free(g->e[i]);
		free(g->visited[i]);
	}
	free(g->e);
	free(g->visited);
	free(g);
}