implement day 5 with hashmaps to gain a 20x speed increase
[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 = {.x=x, .y=y};
13 HASH_FIND(hh, *entries, &s, sizeof(struct point), p);
14 if (p) {
15 if (p->i++ == 1)
16 *r = *r+1;
17 } else {
18 p = malloc(sizeof(struct entry));
19 p->key = s;
20 p->i = 1;
21 HASH_ADD(hh, *entries, key, sizeof(struct point), p);
22 }
23 }
24
25 int main()
26 {
27 char buf[1000];
28 struct entry *entries = NULL;
29 int r = 0;
30 while (fgets(buf, 1000, stdin) != NULL) {
31 char *ptr = &buf[0];
32 int x1 = strtol(ptr, &ptr, 10);
33 ptr++;
34 int y1 = strtol(ptr, &ptr, 10);
35 ptr+=4;
36 int x2 = strtol(ptr, &ptr, 10);
37 ptr++;
38 int y2 = strtol(ptr, &ptr, 10);
39
40 //Diagonal
41 if (abs(y2-y1) == abs(x2-x1)) {
42 int dx = x1 > x2 ? -1 : 1;
43 int dy = y1 > y2 ? -1 : 1;
44 for (; x1 != x2; x1 += dx, y1+= dy)
45 mark_point(x1, y1, &entries, &r);
46 mark_point(x1, y1, &entries, &r);
47 } else {
48 if (x1 > x2)
49 SWAP(x1, x2);
50 if (y1 > y2)
51 SWAP(y1, y2);
52 //Vertical
53 if (x1 == x2)
54 for (int y = y1; y<=y2; y++)
55 mark_point(x1, y, &entries, &r);
56 //Horizontal
57 else if (y1 == y2)
58 for (int x = x1; x<=x2; x++)
59 mark_point(x, y1, &entries, &r);
60 }
61 }
62 printf("%d\n", r);
63 }