-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvirus.c
122 lines (97 loc) · 2.36 KB
/
virus.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
#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_right(&vd);
grid[offset] = '.';
} else {
turn_left(&vd);
grid[offset] = '#';
++bursts_infected;
}
go_forward(&vx, &vy, &vd);
}
print_grid(9);
printf("> %ld new infections\n", bursts_infected);
}