208f870e0de1daae2938dfc31c81e967f24359b9
[advent21.git] / 05b.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4
5 struct line { enum {horz, vert, diag} d; int x1; int y1; int x2; int y2; };
6
7 #define max(x, y) ((x)>(y) ? (x) : (y))
8 #define min(x, y) ((x)<(y) ? (x) : (y))
9 #define between(a, a1, a2) ((a) >= min(a1, a2) && (a) <= max(a1, a2))
10
11 int parse_lines(struct line lines[], int *maxx, int *maxy)
12 {
13 int i = 0;
14 char buf[1000];
15 while (fgets(buf, 1000, stdin) != NULL) {
16 char *p = &buf[0];
17 lines[i].x1 = strtol(p, &p, 10);
18 p++;
19 lines[i].y1 = strtol(p, &p, 10);
20 p+=4;
21 lines[i].x2 = strtol(p, &p, 10);
22 p++;
23 lines[i].y2 = strtol(p, &p, 10);
24 if (lines[i].x1 == lines[i].x2)
25 lines[i].d = vert;
26 else if (lines[i].y1 == lines[i].y2)
27 lines[i].d = horz;
28 else if (abs(lines[i].y2-lines[i].y1) == abs(lines[i].x2-lines[i].x1))
29 lines[i].d = diag;
30 else
31 continue;
32 *maxx = max(*maxx, lines[i].x1);
33 *maxx = max(*maxx, lines[i].x2);
34 *maxy = max(*maxy, lines[i].y1);
35 *maxy = max(*maxy, lines[i].y2);
36 i++;
37 }
38 return i;
39 }
40
41 bool online(int x, int y, struct line line)
42 {
43 int slope;
44 switch (line.d) {
45 case horz:
46 return y == line.y1 && between(x, line.x1, line.x2);
47 case vert:
48 return x == line.x1 && between(y, line.y1, line.y2);
49 case diag:
50 slope = (line.y2 - line.y1) / (line.x2 - line.x1);
51 return y-line.y1 == slope*(x-line.x1)
52 && between(y, line.y1, line.y2) && between(x, line.x1, line.x2);
53 }
54 return false;
55 }
56
57 int main()
58 {
59 struct line lines[1000];
60 int maxx = 0, maxy = 0;
61 int nlines = parse_lines(lines, &maxx, &maxy);
62 int r = 0;
63 for (int x = 0; x<=maxx; x++) {
64 for (int y = 0; y<=maxy; y++) {
65 int matches = 0;
66 for (int line = 0; line<nlines && matches < 2; line++)
67 if (online(x, y, lines[line]))
68 matches++;
69 r = matches >= 2 ? r+1 : r;
70 }
71 }
72 printf("%d\n", r);
73 }