diff --git a/solver.cpp b/solver.cpp index 44a5b3a..3e32304 100644 --- a/solver.cpp +++ b/solver.cpp @@ -12,28 +12,28 @@ void Solver::generate_set(vector carry) { carry.pop_back(); } } - Solver::Solver(int _N, int _M) : N(_N), M(_M) { generate_set({}); } vector Solver::guess() { - // First pick + // Optimal first pick is always the same (at least for 5x8) if(first_pick) { first_pick = false; - vector pick(0); + vector pick = {0}; - int times = N / M + 1; + int times = (N-1) / M + 1; for(int i = 0; i < times; i++) for(int j = 0; j < M && pick.size() < N; j++) pick.push_back(j); return pick; } - + return choose_possible().guess; } void Solver::learn(vector guess, Response response) { + // Eliminating impossible sequences set> next_possible; for(auto sequence : possible) if(validate(sequence, guess) == response) @@ -43,24 +43,27 @@ void Solver::learn(vector guess, Response response) { } int Solver::get_weight(vector guess) { - // Indexing by N*somewhere + correct and holding how many sequences got that response - vector response_count(N*N+1, 0); + // Bucketing possible sequences by responses + vector response_count(N*N+N+1, 0); for(auto sequence : possible) { Response response = validate(sequence, guess); - response_count[N*response.somewhere + response.correct]++; + response_count[(N+1)*response.somewhere + response.correct]++; } - // Get highest possible number of sequences left + // Get size of the fullest bucket int max = 0; for(int count : response_count) if(count > max) max = count; - return max - possible.count(guess); + // Possible guesses have higher priority + return 2*max - possible.count(guess); } +// Choosing next guess Weighed_guess Solver::minimax(vector carry) { if(carry.size() == N) return {get_weight(carry), carry}; + // Pick the best of next picks Weighed_guess best = {-1, {}}; for(int col = 0; col < M; col++) { carry.push_back(col);