-
Notifications
You must be signed in to change notification settings - Fork 0
/
day14b.c
105 lines (91 loc) · 3.1 KB
/
day14b.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
#include "common.h"
#include "stringview.h"
#include "map.h"
#include "vector.h"
void print_binary_u64 (u64 value) {
u64 b = UINT64_C(1) << 63;
do {
if (value & b) {
putchar('1');
} else {
putchar('0');
}
b >>= 1;
} while (b);
}
int main (int argc, char ** argv) {
Map_t memory;
map_init(&memory, 0);
char bitmask [37] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
do {
char buf [BUFSIZ];
char * s = fgets(buf, sizeof(buf), stdin);
if (s == NULL) {
break;
}
StringView_t line = sv_view_c_string(s);
StringView_t target = sv_eat_until_space(&line);
sv_eat_spaces(&line);
char equals = sv_eat_char(&line);
ASSERT(equals == '=');
sv_eat_spaces(&line);
StringView_t value = sv_eat_until_space(&line);
if (sv_equals(&target, "mask")) {
ASSERT(sv_length(&value) == 36);
strncpy(bitmask, value.start, 36);
} else {
StringView_t mem = sv_eat_until_punctuation(&target);
ASSERT(sv_equals(&mem, "mem"));
char openbracket = sv_eat_char(&target);
ASSERT(openbracket == '[');
StringView_t index = sv_eat_until_punctuation(&target);
char closebracket = sv_eat_char(&target);
ASSERT(closebracket == ']');
// TODO: Can't pass StringView_t to strtol et al, as they are not null-terminated
unsigned long addr = strtoul(index.start, NULL, 10);
unsigned long val = strtoul(value.start, NULL, 10);
for (size_t i = 0; i < 36; ++i) {
u64 b = UINT64_C(1) << (35-i);
switch (bitmask[i]) {
case '0': {
// Do nothing
} break;
case '1': {
addr |= b;
} break;
case 'X': {
addr &= ~b;
} break;
}
}
Vector_t addrs;
vector_init(&addrs, 1);
vector_push_back(&addrs, addr);
for (size_t i = 0; i < 36; ++i) {
u64 b = UINT64_C(1) << (35-i);
switch (bitmask[i]) {
case '0': {
// Do nothing
} break;
case '1': {
// Do nothing
} break;
case 'X': {
for (intptr_t const * it = vector_cbegin(&addrs), * end = vector_cend(&addrs); it != end; ++it) {
vector_push_back(&addrs, *it | b);
}
} break;
}
}
for (intptr_t const * it = vector_cbegin(&addrs), * end = vector_cend(&addrs); it != end; ++it) {
map_set(&memory, *it, val);
}
vector_free(&addrs);
}
} while (1);
size_t sum = 0;
for (size_t i = 0; i < memory.count; ++i) {
sum += memory.values[i];
}
DISP(sum);
}