-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDay16.cpp
More file actions
45 lines (41 loc) · 1.17 KB
/
Day16.cpp
File metadata and controls
45 lines (41 loc) · 1.17 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
#include "Solution.hpp"
size_t
dragon_parity(size_t n)
{
size_t gray{n ^ (n >> 1)};
return (gray ^ __builtin_popcountl(n & gray)) & 1;
}
size_t
parity(const std::string& input)
{
auto in{input.data()};
size_t input_parity{0};
for (size_t i{0}, j = input.size() * 2; i < j; ++in, ++i, --j)
input_parity ^= (static_cast<size_t>(*in & 1) << (i + 1)) ^ (static_cast<size_t>((*in & 1) ^ 1) << j);
for (size_t i{1}; i < 64; i <<= 1)
input_parity ^= input_parity << i;
return input_parity;
}
std::string
dragon(const std::string& input, size_t disk_size)
{
std::string out;
const size_t LEN{input.size()}, INCR{disk_size & -disk_size};
size_t par{parity(input)}, prev{0};
for (size_t length{INCR}; length <= disk_size; length += INCR) {
size_t dragons{length / (LEN + 1)},
p{1 & (dragon_parity(dragons) ^ (((length - dragons) / (LEN << 1)) & LEN) ^ (par >> ((length - dragons) % (LEN << 1))))};
out.push_back("10"[p ^ prev]);
prev = p;
}
return out;
}
template <>
void
solve<Day16>(bool part2, std::istream& is, std::ostream& os)
{
const size_t LIM{part2 ? 35651584U : 272U};
std::string in;
is >> in;
os << dragon(in, LIM) << std::endl;
}