cleanup
[advent21.git] / 05b.c
1 #include <stdio.h>
2 #include <uthash.h>
3
4 #define SWAP(x, y) { x ^= y; y ^= x; x ^= y; }
5
6 struct point { int x; int y; };
7 struct entry { struct point key; int i; UT_hash_handle hh; };
8
9 void mark_point(int x, int y, struct entry **entries, int *r)
10 {
11 struct entry *p;
12 struct point s;
13 memset(&s, 0, sizeof s);
14 s.x = x;
15 s.y = y;
16 HASH_FIND(hh, *entries, &s, sizeof(struct point), p);
17 if (p) {
18 if (p->i++ == 1)
19 *r = *r+1;
20 } else {
21 p = calloc(1, sizeof(struct entry));
22 p->key = s;
23 p->i = 1;
24 HASH_ADD(hh, *entries, key, sizeof(struct point), p);
25 }
26 }
27
28 int main()
29 {
30 char buf[1000];
31 struct entry *entries = NULL;
32 int r = 0;
33 while (fgets(buf, 1000, stdin) != NULL) {
34 char *ptr = &buf[0];
35 int x1 = strtol(ptr, &ptr, 10);
36 ptr++;
37 int y1 = strtol(ptr, &ptr, 10);
38 ptr+=4;
39 int x2 = strtol(ptr, &ptr, 10);
40 ptr++;
41 int y2 = strtol(ptr, &ptr, 10);
42
43 //Diagonal
44 if (abs(y2-y1) == abs(x2-x1)) {
45 int dx = x1 > x2 ? -1 : 1;
46 int dy = y1 > y2 ? -1 : 1;
47 for (; x1 != x2; x1 += dx, y1+= dy)
48 mark_point(x1, y1, &entries, &r);
49 mark_point(x1, y1, &entries, &r);
50 } else {
51 if (x1 > x2)
52 SWAP(x1, x2);
53 if (y1 > y2)
54 SWAP(y1, y2);
55 //Vertical
56 if (x1 == x2)
57 for (int y = y1; y<=y2; y++)
58 mark_point(x1, y, &entries, &r);
59 //Horizontal
60 else if (y1 == y2)
61 for (int x = x1; x<=x2; x++)
62 mark_point(x, y1, &entries, &r);
63 }
64 }
65 printf("%d\n", r);
66 }