#include #include #include #include #include #include const size_t BATCH_SIZE = 64; const size_t BATCH_NUM = 4096/BATCH_SIZE; 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) { 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); } std::pair find_first_unique_runs_xor(std::vector *s) { size_t four = 0; size_t fourteen = 0; uint32_t masks[4096]; for (int i=0; i<4096; i++) { masks[i] = 1 << ((*s)[i]-'a'); } uint32_t bitset = 0; for (int i = 0; i < 4; i++) { // No old entries to remove bitset ^= masks[i]; } for (int i = 4; i < 4096; i++) { bitset ^= masks[i]; bitset ^= masks[i-4]; if (std::popcount(bitset) >= 4) { four = i; break; } } for (int i = four+1; i < four+11; i++) { // No old entries to remove while readjusting base bitset ^= masks[i]; } for (int i = four+11; i < 4096; i++) { bitset ^= masks[i]; bitset ^= masks[i-14]; if (std::popcount(bitset) >= 14) { fourteen = i; break; } } return std::pair(four, fourteen); } int main(int argc, char **argv) { size_t iterations = 1000000; auto filename = "input/6"; switch(argc) { case 3: // a.out filename iterations iterations = std::stoi(argv[2]); // std::cout << "Set iterations to: " << iterations << '\n'; // fallthrough case 2: // a.out filename filename = argv[1]; // std::cout << "Set filename to: " << filename << '\n'; default: break; } auto input_file = std::ifstream(filename, std::ios::binary | std::ios::ate); const std::streamoff eof_position = static_cast(input_file.tellg()); auto s = std::vector(eof_position); input_file.seekg(0, std::ios::beg); input_file.read(reinterpret_cast(s.data()), eof_position); size_t volatile four = 0; // Don't you dare optimize out the iterations! size_t volatile fourteen = 0; std::cout << "Running " << iterations << " iterations with batch size " << BATCH_SIZE << ":\n"; auto clock = std::chrono::high_resolution_clock(); auto t0 = clock.now(); for (size_t i = 0; i(delta).count() << "ms (~" << std::chrono::duration_cast(per_iteration).count() << "ns each)\n"; }