-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathday_14b.cpp
73 lines (67 loc) · 2.25 KB
/
day_14b.cpp
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
#include <bitset>
#include <fstream>
#include <iostream>
#include <numeric>
#include <regex>
#include <unordered_map>
#include <vector>
std::string ParseMaskLine(const std::string& line) {
const std::regex mask_pattern(R"(mask = ([10X]+))");
std::smatch mask_match;
std::regex_search(line, mask_match, mask_pattern);
return mask_match[1];
}
std::pair<uint64_t, uint64_t> ParseMemLine(const std::string& line) {
const std::regex mem_pattern(R"(mem\[(\d+)\] = (\d+))");
std::smatch mem_match;
std::regex_search(line, mem_match, mem_pattern);
return {std::stoul(mem_match[1]), std::stoul(mem_match[2])};
}
std::vector<uint64_t> GenerateAddresses(const std::string& mask,
std::bitset<36> address) {
std::vector<uint64_t> floating_bits;
for (int i = 0; i < mask.size(); ++i) {
if (mask[i] == 'X') {
floating_bits.push_back(mask.size() - i - 1);
} else if (mask[i] == '1') {
address[mask.size() - i - 1] = true;
}
}
uint64_t address_count = 1u << floating_bits.size();
std::vector<uint64_t> addresses;
addresses.reserve(address_count);
for (uint64_t bits = 0; bits < address_count; ++bits) {
std::bitset<36> new_address(address);
for (uint64_t i = 0; i < floating_bits.size(); ++i) {
new_address[floating_bits[i]] = (bits & (1u << i)) != 0;
}
addresses.push_back(new_address.to_ullong());
}
return addresses;
}
int main() {
std::fstream file{"../input/day_14_input"};
std::string line;
std::string mask;
std::unordered_map<uint64_t, uint64_t> memory;
while (std::getline(file, line)) {
if (line.substr(0, 4) == "mask") {
mask = ParseMaskLine(line);
} else if (line.substr(0, 3) == "mem") {
const auto [address, value] = ParseMemLine(line);
std::vector<uint64_t> addresses = GenerateAddresses(mask, address);
for (const auto& addr : addresses) {
memory[addr] = value;
}
} else {
std::cout << "This should not happen" << '\n';
}
}
auto acc_func = [](const uint64_t sum, const auto& ele) {
return sum + ele.second;
};
const uint64_t sum = std::accumulate(std::begin(memory), std::end(memory),
(uint64_t)0, acc_func);
std::cout << sum << '\n';
return sum;
}