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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <vector>
using namespace std;
namespace {
vector<string>
split(const string& line, const string& delimiter)
{
vector<string> result;
size_t start = 0;
size_t end = 0;
while ( (end = line.find(delimiter, start)) != string::npos ) {
if ( end != start ) {
result.emplace_back(line.substr(start, end - start));
}
start = end + delimiter.length();
}
if ( start != line.size() ) {
result.emplace_back(line.substr(start));
}
return result;
}
vector<vector<vector<string>>>
read_file(const filesystem::path& filename)
{
ifstream file{ filename };
string content{ istreambuf_iterator<char>{ file }, {} };
vector<vector<vector<string>>> result;
auto blocks = split(content, "\n\n");
for ( const auto& block: blocks ) {
vector<vector<string>> data;
auto lines = split(block, "\n");
for ( auto line: lines ) {
line.pop_back();
auto words = split(line, " ");
data.emplace_back(words);
}
result.emplace_back(data);
}
return result;
}
using action_type = tuple<int, int, string>; // value (0, 1), direction (-1, 1), next_state)
using condition_type = array<action_type, 2>; // [0] -> action, [1] -> action
using rule_type = map<string, condition_type>; // "A" -> condition
using puzzle_type = tuple<string, int, rule_type>; // (start_state, steps, rules)
puzzle_type
parse_input(const vector<vector<vector<string>>>& input)
{
rule_type rules{};
for ( size_t idx = 1; idx < input.size(); ++idx ) {
const auto& block = input.at(idx);
condition_type condition{};
for ( size_t i = 0; i != 2; ++i ) {
const auto base = i * 4;
auto read_val = stoul(block.at(base + 1).back());
auto write_val = stoi(block.at(base + 2).back());
auto dir = block.at(base + 3).back() == "left" ? -1 : 1;
auto next_state = block.at(base + 4).back();
condition.at(read_val) = { write_val, dir, next_state };
}
rules[block.at(0).back()] = condition;
}
auto start_state = input[0][0][3];
auto steps = stoi(input[0][1][5]);
return puzzle_type{ start_state, steps, rules };
}
void
part1(const puzzle_type& puzzle)
{
auto [state, steps, rules] = puzzle;
map<int, int> tape;
int pos = 0;
while ( steps-- > 0 ) {
auto value = tape[pos];
const auto& [write, move, next_state] = rules.at(state).at(size_t(value));
state = next_state;
tape[pos] = write;
pos += move;
}
int sum = 0;
for ( const auto& [key, value]: tape ) {
sum += value;
}
cout << "Part1: " << sum << '\n';
}
} // namespace
int
main()
{
auto input = read_file("data/day25.txt");
part1(parse_input(input));
}
|