#include "slime_solver_core.hpp" #include #include #include #include #include #include #include #include #include namespace sr = slime_research; namespace { struct Args { int32_t x = 51069; int32_t z = 419124; int32_t size = 5; uint64_t start = 0; uint64_t count = 1ULL << 30; int threads = std::max(1U, std::thread::hardware_concurrency()); }; const char* value(int argc, char** argv, int& i) { if (++i >= argc) std::exit(2); return argv[i]; } Args parseArgs(int argc, char** argv) { Args args; for (int i = 1; i < argc; ++i) { const std::string arg = argv[i]; if (arg == "--x") args.x = std::stoi(value(argc, argv, i)); else if (arg == "--z") args.z = std::stoi(value(argc, argv, i)); else if (arg == "-n") args.size = std::stoi(value(argc, argv, i)); else if (arg == "--start") args.start = std::stoull(value(argc, argv, i)); else if (arg == "--count") args.count = std::stoull(value(argc, argv, i)); else if (arg == "-p" || arg == "--threads") args.threads = std::stoi(value(argc, argv, i)); else std::exit(2); } if (args.size <= 0 || int64_t(args.size) * args.size > sr::kMaxPatternCells || args.count == 0 || args.threads <= 0) std::exit(2); return args; } } // namespace int main(int argc, char** argv) { const Args args = parseArgs(argc, argv); std::vector terms; for (int32_t dz = 0; dz < args.size; ++dz) { for (int32_t dx = 0; dx < args.size; ++dx) { terms.push_back({sr::coordinateTerm(args.x + dx, args.z + dz), sr::kSlime}); } } constexpr uint64_t batch = 4096; std::atomic next{0}; std::atomic matches{0}; const auto begin = std::chrono::steady_clock::now(); auto worker = [&] { uint64_t localMatches = 0; for (;;) { const uint64_t first = next.fetch_add(batch, std::memory_order_relaxed); if (first >= args.count) break; const uint64_t last = std::min(first + batch, args.count); for (uint64_t offset = first; offset < last; ++offset) { if (sr::verifyPattern( (args.start + offset) & sr::kMask48, terms.data(), int(terms.size()))) { ++localMatches; } } } matches.fetch_add(localMatches, std::memory_order_relaxed); }; std::vector workers; for (int i = 0; i < args.threads; ++i) workers.emplace_back(worker); for (std::thread& workerThread : workers) workerThread.join(); const std::chrono::duration elapsed = std::chrono::steady_clock::now() - begin; const double seedsPerSecond = double(args.count) / elapsed.count(); const double fullSeconds = double(1ULL << 48) / seedsPerSecond; std::cout << "count=" << args.count << " matches=" << matches.load() << " seconds=" << elapsed.count() << " seeds_per_second=" << seedsPerSecond << " projected_full48_seconds=" << fullSeconds << '\n'; }