171 lines
4.5 KiB
C++
171 lines
4.5 KiB
C++
// aoc5.cpp : This file contains the 'main' function. Program execution begins and ends there.
|
|
//
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <atomic>
|
|
#include <omp.h>
|
|
|
|
typedef uint32_t Numero;
|
|
|
|
struct MapEntry {
|
|
Numero src_start;
|
|
Numero dest_start;
|
|
Numero size;
|
|
};
|
|
|
|
int main() {
|
|
std::vector<MapEntry> maps[7];
|
|
|
|
std::vector<int> tovjemam;
|
|
|
|
|
|
std::ifstream ifs("input_richaj");
|
|
|
|
std::string hovno;
|
|
std::string line;
|
|
std::getline(ifs, line);
|
|
std::istringstream iss(line);
|
|
|
|
std::vector<Numero> 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;
|
|
maps[map_idx].push_back(ent);
|
|
}
|
|
|
|
auto start_time = std::chrono::system_clock::now();
|
|
|
|
int num_ranges = seeds.size() / 2;
|
|
|
|
std::vector<Numero> min_locs;
|
|
min_locs.resize(num_ranges);
|
|
std::atomic_int progress[32];
|
|
|
|
std::thread progress_thread([num_ranges, &progress]() {
|
|
|
|
|
|
while (true) {
|
|
bool finished = true;
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
for (int i = 0; i < num_ranges; ++i) {
|
|
int p = progress[i].load();
|
|
|
|
if (p != 100)
|
|
finished = false;
|
|
|
|
char pb[] = " ";
|
|
|
|
for (int c = 0; c < p; ++c)
|
|
pb[c] = '#';
|
|
|
|
|
|
printf("%6d%% [%s]\n", p, pb);
|
|
|
|
}
|
|
printf("\n\n");
|
|
|
|
if (finished)
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
//progress_thread.detach();
|
|
|
|
omp_set_num_threads(8);
|
|
|
|
//#pragma omp parallel for
|
|
for (int r = 0; r < num_ranges; r++) {
|
|
Numero min_loc = UINT32_MAX;
|
|
|
|
Numero start = seeds[r * 2];
|
|
Numero end = start + seeds[r * 2 + 1];
|
|
|
|
for (Numero seed = start; seed < end; ++seed) {
|
|
Numero find_what = seed;
|
|
|
|
Numero skip = end - start;
|
|
|
|
|
|
for (int i = 0; i < 7; ++i) {
|
|
const auto& map = maps[i];
|
|
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);
|
|
|
|
//printf("-> %lu\n", find_what);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
min_loc = std::min(min_loc, find_what);
|
|
if (seed % 1000000 == 0)
|
|
progress[r] = (float)(seed - start) / (float)(end - 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 - 1;
|
|
}
|
|
|
|
progress[r] = 100;
|
|
min_locs[r] = min_loc;
|
|
|
|
|
|
}
|
|
|
|
auto end_time = std::chrono::system_clock::now();
|
|
|
|
progress_thread.join();
|
|
|
|
Numero min_loc = UINT32_MAX;
|
|
for (int i = 0; i < num_ranges; ++i) {
|
|
printf("vysledek range %d: %u\n", i, min_locs[i]);
|
|
min_loc = std::min(min_loc, min_locs[i]);
|
|
}
|
|
|
|
printf("=======\nvysledek: %u\n", min_loc);
|
|
|
|
auto time_total = end_time - start_time;
|
|
printf("time total: %lld s\n", std::chrono::duration_cast<std::chrono::seconds>(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
|