-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathq9.cpp
79 lines (66 loc) · 2.52 KB
/
q9.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
74
75
76
77
78
79
#include <boost/algorithm/string/classification.hpp> // for boost::is_any_of
#include <boost/algorithm/string/split.hpp> // for boost::split
#include <fmt/format.h>
#include <fstream>
#include <iostream>
#include <numeric>
template<typename T>
[[nodiscard]] std::vector<T> vectorize(std::ifstream& is) {
std::vector<T> vec;
T str;
while(std::getline(is, str)){
vec.push_back(str);
}
return vec;
}
template<typename T>
[[nodiscard]] std::vector<std::vector<int>> tokenize(const std::vector<T>& lines_of_data) {
std::vector<std::vector<int>> tokenized_lines_of_data;
for (const auto& line : lines_of_data) {
const std::vector<std::string> tokens = [&](){
std::vector<std::string> tokens;
boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on);
return tokens;
}();
const std::vector<int> int_tokens = [&](){
std::vector<int> int_tokens;
int_tokens.reserve(tokens.size());
for (const auto &token: tokens) {
int_tokens.push_back(std::stoi(token));
}
return int_tokens;
}();
tokenized_lines_of_data.push_back(int_tokens);
}
return tokenized_lines_of_data;
}
std::vector<std::vector<int>> parse(std::string_view file_name) {
std::ifstream data(file_name);
return tokenize(vectorize<std::string>(data));
}
enum class End {FRONT, BACK};
[[nodiscard]] int predict_next_num_in_sequence(std::vector<int> vec, End predicting) {
if (std::ranges::all_of(vec, [&](const int num){ return vec[0] == num; })) {
return vec[0];
}
else {
const auto prev = vec;
std::adjacent_difference(begin(vec), end(vec), begin(vec));
vec.erase(begin(vec));
const auto nth_most = (predicting == End::FRONT) ? prev.front() : prev.back();
const int multiplier = (predicting == End::FRONT) ? -1 : 1;
return nth_most + multiplier * predict_next_num_in_sequence(vec, predicting);
}
}
int main() {
const auto sequences = parse("../sequences.txt");
const auto part_1 = std::accumulate(cbegin(sequences), cend(sequences), 0, [](int acc, const auto& seq){
return acc + predict_next_num_in_sequence(seq, End::BACK);
});
const auto part_2 = std::accumulate(cbegin(sequences), cend(sequences), 0, [](int acc, const auto& seq){
return acc + predict_next_num_in_sequence(seq, End::FRONT);
});
fmt::print("Part 1: {}\n", part_1);
fmt::print("Part 2: {}\n", part_2);
return 0;
}