77 lines
1.8 KiB
C++
77 lines
1.8 KiB
C++
#include <iostream>
|
|
#include <optional>
|
|
#include <vector>
|
|
#include <numeric>
|
|
|
|
#include <aocpp/Startup.hpp>
|
|
using namespace aocpp;
|
|
|
|
namespace {
|
|
|
|
auto FFT(std::size_t start, std::vector<std::int8_t> const& prev)
|
|
{
|
|
std::vector<std::int8_t> result;
|
|
std::vector<std::int32_t> partial_sums;
|
|
auto n = prev.size();
|
|
result.resize(n);
|
|
partial_sums.reserve(n+1);
|
|
partial_sums.push_back(0);
|
|
|
|
std::int32_t acc = 0;
|
|
for (auto const x : prev) {
|
|
partial_sums.push_back(acc += x);
|
|
}
|
|
|
|
for (std::size_t i = start; i < n+start; i++) {
|
|
std::int32_t acc = 0;
|
|
for (std::size_t offset = i; offset < n+start; offset += 4*(i+1)) {
|
|
acc += partial_sums[std::min(n,offset-start + i + 1)] - partial_sums[std::min(n, offset-start)];
|
|
acc -= partial_sums[std::min(n, offset-start + 3*(i + 1))] - partial_sums[std::min(n, offset-start + 2*(i + 1))];
|
|
}
|
|
|
|
result[i-start] = std::abs(acc % 10);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
auto main(int argc, char** argv) -> int {
|
|
auto & in = aocpp::Startup(argc, argv);
|
|
std::string input;
|
|
in >> input;
|
|
|
|
std::vector<std::int8_t> signal;
|
|
for (char const c : input) {
|
|
signal.push_back(c - '0');
|
|
}
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
signal = FFT(0, signal);
|
|
}
|
|
for (int i = 0; i < 8; i++) {
|
|
std::cout << int(signal[i]);
|
|
}
|
|
std::cout << std::endl;
|
|
|
|
signal.clear();
|
|
signal.reserve(10000 * input.size());
|
|
for (int i = 0; i < 10000; i++) {
|
|
for (char const c : input) {
|
|
signal.push_back(c - '0');
|
|
}
|
|
}
|
|
|
|
auto offset = std::stol(input.substr(0,7));
|
|
std::copy(signal.begin() + offset, signal.end(), signal.begin());
|
|
signal.resize(signal.size() - offset);
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
signal = FFT(offset, signal);
|
|
}
|
|
|
|
for (auto i = 0; i < 8; i++) {
|
|
std::cout << int(signal[i]);
|
|
}
|
|
std::cout << std::endl;
|
|
} |