// assigns to "result" size-32 vectors representing // all elements in episode, in order, that occur at least twice // runtime: O(N log N) where N = distance(first, last) static void makeNoislessInputs(Episode::const_iterator first, Episode::const_iterator last, LSTMInput& result) { std::set<enc_t> singles(first, last); std::set<enc_t> noise(singles); for (Episode::const_iterator it = first; it != last; ++it) { std::set<enc_t>::iterator sit = singles.find(*it); if (sit != singles.end()) { singles.erase(sit); // first occurrence } else { noise.erase(*it); // second occurrence means not noise } } result.assign(std::distance(first, last) - noise.size(), LSTMState(32)); uint64_t i = 0; for (Episode::const_iterator it = first; it != last; ++it) { enc_t code = *it; if (noise.find(code) == noise.end()) { for (uint64_t j = 0, b = 1 << 31; j < 32; ++j, b >>= 1) { result[i][j] = code & b ? 1 : 0; } ++i; } } }
/* Given the board state, find all possible 'moves' (i.e. squares with just * a single digit). * * Returns the number of (deterministic) moves (and fills the moves array), * or 0 if no moves are possible. This function does not mutate the board * state, and hence, can return the same move multiple times (with * different hints). */ static int findmoves( void ) { int i; rb->yield(); idx_possible = 0; for( i = 0 ; i < 9 ; ++i ) { singles( i, idx_row, HINT_ROW ); singles( i, idx_column, HINT_COLUMN ); singles( i, idx_block, HINT_BLOCK ); } return idx_possible; }