#include #include #include #include #include #include #include #include using namespace std; struct Result { int h, b; bool operator<(const Result& other) const { if (h != other.h) return h < other.h; return b < other.b; } bool operator==(const Result& other) const { return h == other.h && b == other.b; } }; Result get_hb(const string& q, const string& t) { int h = 0, common = 0; int mask_t = 0; for (char c : t) mask_t |= (1 << (c - '0')); for (int i = 0; i < 5; ++i) { if (q[i] == t[i]) h++; if (mask_t & (1 << (q[i] - '0'))) common++; } return {h, common - h}; } bool is_valid(const string& s) { int mask = 0; for (char c : s) { int bit = 1 << (c - '0'); if (mask & bit) return false; mask |= bit; } return true; } double calculate_entropy(const string& q, const vector& candidates, int sample_size) { if (candidates.empty()) return 0; map counts; int n = candidates.size(); int actual_sample = min(n, sample_size); static mt19937 rng(42); if (n <= sample_size) { for (const auto& c : candidates) counts[get_hb(q, c)]++; } else { for (int i = 0; i < actual_sample; ++i) { counts[get_hb(q, candidates[rng() % n])]++; } } double entropy = 0; for (auto const& [res, count] : counts) { double p = (double)count / actual_sample; entropy -= p * log2(p); } return entropy; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); vector all_possible; for (int i = 0; i <= 99999; i++) { string cur = to_string(i); while (cur.size() < 5) cur = "0" + cur; if (is_valid(cur)) all_possible.push_back(cur); } vector candidates = all_possible; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); while (true) { string best_q; if (candidates.size() == all_possible.size()) { best_q = "01234"; } else if (candidates.size() <= 30) { best_q = candidates[0]; } else { double max_entropy = -1.0; for (int i = 0; i < 50; ++i) { string test_q = all_possible[rng() % all_possible.size()]; double e = calculate_entropy(test_q, candidates, 300); if (e > max_entropy) { max_entropy = e; best_q = test_q; } } auto start_t = chrono::steady_clock::now(); while (chrono::duration_cast(chrono::steady_clock::now() - start_t).count() < 50) { string next_q = best_q; if (rng() % 2 == 0) { swap(next_q[rng() % 5], next_q[rng() % 5]); } else { int pos = rng() % 5; char nv = '0' + (rng() % 10); next_q[pos] = nv; } if (!is_valid(next_q)) continue; double e = calculate_entropy(next_q, candidates, 300); if (e > max_entropy) { max_entropy = e; best_q = next_q; } } } cout << best_q << "\n"; fflush(stdout); vector> hb(30); map response_counts; for (int i = 0; i < 30; i++) { cin >> hb[i].first >> hb[i].second; response_counts[{hb[i].first, hb[i].second}]++; } if (hb[0].first == 5) break; vector next_candidates; for (const auto& c : candidates) { Result r = get_hb(best_q, c); if (response_counts.count(r) && response_counts[r] > 0) { next_candidates.push_back(c); } } if (!next_candidates.empty()) { candidates = move(next_candidates); } } return 0; }