-
Notifications
You must be signed in to change notification settings - Fork 2
/
12.c
115 lines (103 loc) · 2.53 KB
/
12.c
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define M_PI 3.14159265358979323846 /* pi */
struct instruction {
int value;
char action;
};
struct position {
int x;
int y;
};
struct ship {
struct position pos;
struct position waypoint;
};
static void
move_waypoint(struct ship* ship, const char dir, const int value) {
switch (dir) {
case 'N':
ship->waypoint.y += value;
break;
case 'E':
ship->waypoint.x += value;
break;
case 'S':
ship->waypoint.y -= value;
break;
case 'W':
ship->waypoint.x -= value;
break;
}
}
static void err(int status, char *message) {
fputs(message, stderr);
exit(status);
}
static void
rotate_waypoint(struct ship* ship, const int value) {
const double v = (double)value * M_PI / 180.0;
const int x1 = round(ship->waypoint.x * cos(v) - ship->waypoint.y * sin(v));
const int y1 = round(ship->waypoint.x * sin(v) + ship->waypoint.y * cos(v));
ship->waypoint.x = x1;
ship->waypoint.y = y1;
}
int day12(void) {
int instructions_n = 0;
struct instruction instructions[1024];
FILE* f = fopen("inputs/12.txt", "r");
if (!f) {
err(EXIT_FAILURE, "error reading input file");
}
char linebuf[BUFSIZ] = {0};
while (fgets(linebuf, BUFSIZ, f) != NULL) {
struct instruction* ins = &instructions[instructions_n++];
char* s = linebuf;
// parse single character
ins->action = *s++;
// parse digit
ins->value = 0;
while (*s >= '0' && *s <= '9') {
ins->value = (ins->value * 10) + (*s - '0');
s++;
}
}
fclose(f);
struct ship ship = {
.pos = {0, 0},
.waypoint = {10, 1},
};
for (int i = 0; i < instructions_n; i++) {
struct instruction ins = instructions[i];
#ifdef STEP
printf("ship <%d, %d> \twaypoint <%d, %d>.\n", ship.pos.x, ship.pos.y,
ship.waypoint.x, ship.waypoint.y);
printf("%c%d\n", ins.action, ins.value);
getc(stdin);
#endif
switch (ins.action) {
case 'F':
ship.pos.x += ship.waypoint.x * ins.value;
ship.pos.y += ship.waypoint.y * ins.value;
break;
case 'N':
case 'E':
case 'S':
case 'W':
move_waypoint(&ship, ins.action, ins.value);
break;
case 'L':
rotate_waypoint(&ship, ins.value);
break;
case 'R':
rotate_waypoint(&ship, -ins.value);
break;
}
}
int manhattan_distance = abs(ship.pos.x) + abs(ship.pos.y);
printf("%d\n", manhattan_distance);
assert(manhattan_distance == 46530);
return 0;
}