-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
74 lines (64 loc) · 2.23 KB
/
main.cpp
File metadata and controls
74 lines (64 loc) · 2.23 KB
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
#include <stdio.h>
#include <string.h>
#include "AoC64.h"
#include "reucpy.h"
#if __has_include("input.h")
#include "input.h" // user’s private input (gitignored)
#else
#include "input.example.h" // checked-in sample input
#endif
constexpr int8_t N_LETTERS = 26;
static uint64_t pfreq[N_LETTERS*N_LETTERS] = {0};
static uint64_t pfreq_new[N_LETTERS*N_LETTERS] = {0};
static uint64_t lfreq[N_LETTERS] = {0};
#define idx(pair) ((*(pair) - 'A')*26 + *((pair) + 1) - 'A')
void polymerize(const int8_t niter) {
for (int8_t s = 0; s < niter; ++s) {
memcpy_reu(pfreq_new, pfreq, N_LETTERS*N_LETTERS*sizeof(pfreq[0]));
for (int8_t i = 0; i < n_rules; ++i) {
tick((i >> 4) & (uint8_t)7);
const char* const pair = rules[i][0];
const int16_t ri = idx(pair);
const uint64_t pcount = pfreq[ri];
if (pcount > 0) {
const char new_element = rules[i][1][0];
lfreq[new_element - 'A'] += pcount;
char new_pair[3] = {pair[0], new_element, pair[1]};
pfreq_new[idx(new_pair)] += pcount;
pfreq_new[idx(new_pair+1)] += pcount;
pfreq_new[ri] -= pcount;
}
}
memcpy_reu(pfreq, pfreq_new, N_LETTERS*N_LETTERS*sizeof(pfreq[0]));
}
}
int main(void) {
init(14);
// initialize frequency tables with the initial polymer template
const int8_t template_len = strlen(polymer_template);
for (int8_t i = 0; i < template_len; ++i) {
if (i < template_len - 1)
pfreq[idx(polymer_template + i)] += 1;
lfreq[polymer_template[i] - 'A'] += 1;
}
// part 1
polymerize(10);
uint64_t min = UINT64_MAX, max = 0;
for (int8_t i = 0; i < N_LETTERS; ++i) {
if (lfreq[i] == 0) continue;
if (lfreq[i] < min) min = lfreq[i];
if (lfreq[i] > max) max = lfreq[i];
}
printf("part 1: %lld\n", max - min);
// part 2
polymerize(30);
min = UINT64_MAX, max = 0;
for (int8_t i = 0; i < N_LETTERS; ++i) {
if (lfreq[i] == 0) continue;
if (lfreq[i] < min) min = lfreq[i];
if (lfreq[i] > max) max = lfreq[i];
}
printf("part 2: %lld\n", max - min);
printf("\n");
finish();
}