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
|
#include "aoc.h"
namespace aoc2017 {
uint64_t generator(uint64_t x, uint64_t factor) { return x * factor % 2147483647; }
bool lower16(uint64_t x) {
uint8_t i[8] = {0};
memcpy(i, &x, 8);
return i[0] == 0 && i[1] == 0;
}
int forty_million(uint64_t a, uint64_t b) {
int t{0};
constexpr size_t mi = 40 * 1000000;
for (size_t i = 0; i < mi; i++) {
a = generator(a, 16807);
b = generator(b, 48271);
t += (int)lower16(a ^ b);
}
return t;
}
int five_million(uint64_t a, uint64_t b) {
int t{0};
constexpr size_t mi = 5 * 1000000;
size_t p{0};
uint64_t n2[2] = {0, 0};
while (p < mi) {
if (n2[0] == 0) {
a = generator(a, 16807);
if (a % 4 == 0) {
n2[0] = a;
}
}
if (n2[1] == 0) {
b = generator(b, 48271);
if (b % 8 == 0) {
n2[1] = b;
}
}
if (n2[0] > 0 && n2[1] > 0) {
t += (int)lower16(n2[0] ^ n2[1]);
n2[0] = 0;
n2[1] = 0;
p++;
}
}
return t;
}
// Generator A starts with 873
// Generator B starts with 583
std::pair<int64_t, int64_t> day15(line_view) {
// uint64_t a = 65;
// uint64_t b = 8921;
uint64_t a = 873;
uint64_t b = 583;
return {forty_million(a, b), five_million(a, b)};
}
} // namespace aoc2017
|