// aoc5.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include #include #include #include #include #include #include #include #include #define NOMINMAX #include #define NUM_THREADS 10 typedef uint64_t Numero; struct MapEntry { Numero src_start; Numero src_end; Numero dest_start; Numero size; }; int main() { std::vector maps[7]; std::vector tovjemam; std::ifstream ifs("input_richaj"); std::string hovno; std::string line; std::getline(ifs, line); std::istringstream iss(line); std::vector seeds; iss >> hovno; Numero seed; while (iss >> seed) seeds.push_back(seed); int map_idx = -1; while (std::getline(ifs, line)) { if (line == "") { map_idx++; std::getline(ifs, line); continue; } std::istringstream iss(line); MapEntry ent; iss >> ent.dest_start >> ent.src_start >> ent.size; ent.src_end = ent.src_start + ent.size; maps[map_idx].push_back(ent); } auto start_time = std::chrono::system_clock::now(); for (map_idx = 0; map_idx < 7; ++map_idx) { std::sort(maps[map_idx].begin(), maps[map_idx].end(), [](MapEntry& a, MapEntry& b) { return a.src_start < b.src_start; }); } int num_ranges = seeds.size() / 2; Numero min_locs[NUM_THREADS]; std::atomic_int progress[NUM_THREADS]; bool finished = false; std::atomic_int current_range; current_range.store(0); std::thread progress_thread([&progress, &finished, &min_locs, num_ranges, ¤t_range]() { HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos = { 0, 0 }; while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); SetConsoleCursorPosition(output, pos); printf("RANGE %d/%d\n", current_range.load() + 1, num_ranges); for (int i = 0; i < NUM_THREADS; ++i) { int p = progress[i].load(); char pb[] = " "; for (int c = 0; c < p; ++c) pb[c] = '#'; printf("Thread %-2d %3d%% [%s]\n", i + 1, p, pb); } printf("\n\n"); if (finished) break; } }); //progress_thread.detach(); omp_set_num_threads(NUM_THREADS); //Numero thread_start[8]; Numero thread_ranges[NUM_THREADS + 1]; Numero min_loc_total = UINT64_MAX; for (int r = 0; r < num_ranges; r++) { Numero start = seeds[r * 2]; Numero end = start + seeds[r * 2 + 1]; Numero seed_count = end - start; Numero seeds_per_thread = seed_count / NUM_THREADS; //thread_ranges[0] = start; for (int i = 0; i < NUM_THREADS; ++i) { thread_ranges[i] = start + i * seeds_per_thread; } thread_ranges[NUM_THREADS] = end; current_range.store(r); #pragma omp parallel for for (int t = 0; t < NUM_THREADS; ++t) { Numero min_loc = UINT64_MAX; Numero t_start = thread_ranges[t]; Numero t_end = thread_ranges[t + 1]; progress[t] = 0; for (Numero seed = t_start; seed < t_end; seed++) { Numero find_what = seed; for (int i = 0; i < 7; ++i) { const auto& map = maps[i]; int range_start = 0; int range_end = map.size() - 1; while (range_start <= range_end) { int range_idx = range_start + (range_end - range_start) / 2; const auto& range = map[range_idx]; if (find_what < range.src_start) { range_end = range_idx - 1; } else if (find_what >= range.src_end) { range_start = range_idx + 1; } else { find_what = find_what - range.src_start + range.dest_start; break; } //if (find_what < range.src_start) { // range_end = range_idx; // if (range_end - range_start < 2) // break; // continue; //} //else if (range.src_start + range.size <= find_what) { // range_start = range_idx; // if (range_end - range_start < 2) // break; // continue; //} //else { // find_what = find_what - range.src_start + range.dest_start; // break; //} } //for (const auto& range : map) { // if (range.src_start <= find_what && (range.src_start + range.size) > find_what) { // find_what = find_what - range.src_start + range.dest_start; // //skip = std::min(skip, (range.src_start + range.size) - find_what); // break; // } //} } min_loc = std::min(min_loc, find_what); if (seed % 1000000 == 0) progress[t] = (float)(seed - t_start) / (float)(t_end - t_start) * 100.0f; //printf("r %d/%d seed %llu (%.2f%%) min_loc %llu\n", r + 1, num_ranges, seed, (float)(seed - start) / (float)(end - start) * 100.0f, min_loc); //seed += skip; } progress[t] = 100; min_locs[t] = min_loc; } for (int i = 0; i < NUM_THREADS; ++i) { //printf("vysledek thread %d: %llu\n", i, min_locs[i]); min_loc_total = std::min(min_loc_total, min_locs[i]); } //printf("=======\mezivysledek: %llu\n", min_loc_total); } auto end_time = std::chrono::system_clock::now(); finished = true; progress_thread.join(); printf("=======\nvysledek: %llu\n", min_loc_total); auto time_total = end_time - start_time; printf("time total: %lld s\n", std::chrono::duration_cast(time_total).count()); std::cout << "Hello World!\n"; } // Run program: Ctrl + F5 or Debug > Start Without Debugging menu // Debug program: F5 or Debug > Start Debugging menu // Tips for Getting Started: // 1. Use the Solution Explorer window to add/manage files // 2. Use the Team Explorer window to connect to source control // 3. Use the Output window to see build output and other messages // 4. Use the Error List window to view errors // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file