#include #include #include #include #include bool substring_unique_copyless(std::vector *s, size_t right, size_t length) { for (size_t i = (right-length); i *s, size_t num, size_t skip) { for (size_t right = skip; rightsize(); right++) { if (substring_unique_copyless(s, right, num)) { return right; } } return 0; } std::pair find_first_unique_runs(std::vector *s) { const size_t BATCH_SIZE = 8; const size_t BATCH_NUM = 4096/BATCH_SIZE; size_t four = 0; size_t fourteen = 0; uint32_t masks[4096]; uint32_t scratch_masks[BATCH_SIZE]; uint8_t scratch_masks_bits[BATCH_SIZE]; for (int i=0; i<4096; i++) { masks[i] = 1 << ((*s)[i]-'a'); } // Turn masks into masks2. Indices are now +1. for (int i=0; i<4095; i++) { masks[i] |= masks[i+1]; } for (int batch=1; batch(four+2, fourteen+8); } void run_once(std::vector *s) { size_t four = find_first_unique_run(s, 4, 4); size_t fourteen = find_first_unique_run(s, 14, four); std::cout << "Part 1: " << four << '\n'; std::cout << "Part 2: " << fourteen << '\n'; } void run_many(std::vector *s, size_t iterations) { size_t volatile four = 0; // Don't you dare optimize out the iterations! size_t volatile fourteen = 0; std::cout << "Running " << iterations << " iterations:\n"; for (size_t i = 0; i result = find_first_unique_runs(s); four = result.first; fourteen = result.second; } std::cout << "Part 1: " << four << '\n'; std::cout << "Part 2: " << fourteen << '\n'; std::cout << "Completed " << iterations << " iterations\n"; } int main() { std::ifstream input_file("input/6", std::ios::binary | std::ios::ate); const std::streamoff eof_position = static_cast(input_file.tellg()); std::vector input = std::vector(eof_position); input_file.seekg(0, std::ios::beg); input_file.read(reinterpret_cast(input.data()), eof_position); // run_once(&input); run_many(&input, 10000000); }