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
|
#include "aoc.h"
#include <functional>
#include <string.h>
namespace aoc2022 {
static int X = 1;
static int cycles = 1;
static int get_number(const char *p) {
int sign = *p == '-' ? -1 : 1;
if (sign == -1) p++;
int d{0};
while(*p >= '0' && *p <= '9') {
d = d * 10 + *p - '0';
p++;
}
return sign * d;
}
struct CP {
int d{0};
bool done = false;
CP(int x): d(x) {}
};
void point(int d, CP cp[], int* total) {
// printf("cycle %d X %d\n", d, X);
for (int i = 0; i < 6; i++) {
if (!cp[i].done && cp[i].d == d) {
*total += X * d;
// printf("%d: %d = %d\n", d, X, X * d);
cp[i].done = true;
break;
}
}
}
// static void print(char p[]) {
// for(int i = 0; i < 240; i++) {
// printf("%c", p[i]);
// if ((i+1) % 40 == 0) {
// printf("\n");
// }
// }
// }
static void draw(int i, char crt[], char c) {
crt[i - 1] = c;
}
static void reset(char crt[]) {
for (int i = 0; i < 240; i++) {
* (crt + i) = '.';
}
}
static void set(char crt[], int x) {
reset(crt);
crt[x] = '#';
crt[x+1] = '#';
crt[x+2] = '#';
}
std::pair<int, int> day10(line_view file)
{
char screen[240] = {0};
char sprite[240] = {0};
reset(screen);
set(sprite, X);
struct {
const char *cmd;
std::function<void(const char*, CP [], int*, char [])> f;
} cmds[] = {
{"addx", [&sprite](const char* p, CP cp[], int* total, char crt[]){
auto d = get_number(p);
point(cycles, cp, total);
draw(cycles, crt, sprite[cycles % 40]);
cycles += 1;
point(cycles, cp, total);
draw(cycles, crt, sprite[cycles % 40]);
cycles += 1;
X += d;
set(sprite, X);
}},
{"noop", [&sprite](const char* p, CP cp[], int* total, char crt[]){
// printf("noop\n");
point(cycles, cp, total);
draw(cycles, crt, sprite[cycles % 40]);
cycles += 1;
}},
};
CP cp[] = {20, 60, 100, 140, 180, 220};
int total{0};
per_line(file, [&cmds, &cp, &total, &screen](line_view lv) {
for(auto &c: cmds) {
if (strncmp(c.cmd, lv.line, 4) == 0) {
c.f(lv.line+5, cp, &total, screen);
break;
}
}
return true;
});
// print(screen);
return {total, 0};
}
} // namespace aoc2022
|