-
Notifications
You must be signed in to change notification settings - Fork 0
/
virus2.c
131 lines (106 loc) · 2.6 KB
/
virus2.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GRID_HALF 10000
#define GRID_SIZE (2 * GRID_HALF + 1)
#define OFFSET(x, y) ((y) * GRID_SIZE + (x))
char grid[GRID_SIZE * GRID_SIZE];
long int bursts_total;
void print_grid(const int size) {
int x = GRID_HALF - (size / 2);
int y = GRID_HALF - (size / 2);
char buffer[size+1];
for(int i = 0; i < size; ++i) {
long int offset = OFFSET(x, y+i);
memcpy(buffer, grid + offset, size);
buffer[size] = '\0';
puts(buffer);
}
}
void process_args(int argc, char **argv) {
if(argc < 3) {
fprintf(stderr, "You must provide the number of bursts to process: \"--bursts X\"\n");
exit(EXIT_FAILURE);
}
if(strcmp(argv[1], "--bursts") == 0) {
bursts_total = atoi(argv[2]);
if(bursts_total < 1) {
fprintf(stderr, "The number of bursts must be at least 1\n");
exit(EXIT_FAILURE);
}
} else {
fprintf(stderr, "Unknown option \"%s\"\n", argv[1]);
exit(EXIT_FAILURE);
}
}
void init_buffer(void) {
memset(grid, '.', GRID_SIZE * GRID_SIZE);
}
void process_input(void) {
int lineNo = 0;
char buffer[128];
while(fgets(buffer, sizeof(buffer), stdin) != NULL) {
int buflen = strlen(buffer);
if(buffer[buflen-1] == '\n') buffer[--buflen] = '\0';
int x = GRID_HALF - (buflen / 2);
int y = GRID_HALF - (buflen / 2) + lineNo;
long int offset = OFFSET(x, y);
memcpy(grid + offset, buffer, buflen);
++lineNo;
}
}
enum Direction {
DIR_UP,
DIR_RI,
DIR_DO,
DIR_LE
};
void turn_left(enum Direction *const dir) {
*dir = (*dir == DIR_UP) ? DIR_LE : (*dir - 1);
}
void turn_right(enum Direction *const dir) {
*dir = (*dir + 1) % 4;
}
void go_forward(int *const x, int *const y, const enum Direction *const dir) {
if(*dir == DIR_UP)
*y -= 1;
if(*dir == DIR_RI)
*x += 1;
if(*dir == DIR_DO)
*y += 1;
if(*dir == DIR_LE)
*x -= 1;
}
int main(int argc, char **argv) {
process_args(argc, argv);
init_buffer();
process_input();
int vx = GRID_HALF;
int vy = GRID_HALF;
enum Direction vd = DIR_UP;
long int bursts_infected = 0;
for(long int b = 0; b < bursts_total; ++b) {
long int offset = OFFSET(vx, vy);
if(grid[offset] == '.') {
turn_left(&vd);
grid[offset] = 'W';
} else if(grid[offset] == 'W') {
grid[offset] = '#';
++bursts_infected;
} else if(grid[offset] == '#') {
turn_right(&vd);
grid[offset] = 'F';
} else if(grid[offset] == 'F') {
turn_right(&vd);
turn_right(&vd);
grid[offset] = '.';
} else {
fprintf(stderr, "wtf?\n");
exit(EXIT_FAILURE);
}
go_forward(&vx, &vy, &vd);
}
print_grid(9);
printf("> %ld new infections\n", bursts_infected);
}