#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <memory.h>
#include <vector>
using namespace std;
int numcards=26;
unsigned int mask=0;
int getCorrect(int a, int b)
{
//MIT HackMEM method for counting bits
unsigned int n = (~(a ^ <img src='http://brainden.com/forum/public/style_emoticons/<#EMO_DIR#>/cool.png' class='bbc_emoticon' alt='B))' /> & mask;
register unsigned int tmp;
tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);
return ((tmp + (tmp >> 3)) & 030707070707) % 63;
}
void printbin(int byte)
{
for (int i = 0; i < numcards; i++)
{
if (byte & (1 << i))
printf("1");
else
printf("0");
}
}
vector <int> *pruneit(int guess, int goal, vector <int> *poss)
{
vector <int> *newposs = new vector<int>;
for(int i = 0; i < poss->size(); i++)
{
if (getCorrect(guess,poss->at(i)) == goal)
{
newposs->push_back(poss->at(i));
}
}
delete poss;
return newposs;
}
int getintfrombin()
{
char buffer[64];
memset(buffer,0,sizeof(char)*64);
cin >> buffer;
int thenum = 0;
for(int i = 0; i < numcards; i++)
{
if (buffer[i] == '1')
{
thenum += 1<<i;
}
}
return thenum;
}
int main(int argc, char *argv[])
{
if (argc > 1)
{
numcards = atoi(argv[1]);
}
mask = (1<<(numcards)) - 1;
vector <int> *poss = new vector <int>;
vector<int> guesses;
vector<int> responses;
int totals[numcards+1];
int command;
while (1)
{
if (guesses.size() > 0)
{
cout << endl;
cout << "Guess/Response List" << endl;
for(int i = 0; i < guesses.size(); i++)
{
printbin(guesses.at(i));
cout << " (" << guesses.at(i) << ") - " << responses.at(i) << endl;
}
}
if (poss->size() > 0)
{
cout << "Possibilities left == " << poss->size() << endl;
}
cout << "0 - Reset." << endl;
cout << "1 - Check guess." << endl;
cout << "2 - Check binary guess." << endl;
cout << "3 - Find best guess." << endl;
cout << "4 - Enter guess and response." << endl;
cout << "5 - Enter binary guess and response." << endl;
cout << "6 - List Possibilities." << endl;
cout << "7 - Convert bin to int." << endl;
cout << "8 - Find best guess in remaining items." << endl;
cout << "Enter Command: ";
cin >> command;
if (command == 0)
{
responses.clear();
guesses.clear();
poss->clear();
}
if ((command == 1) || (command == 2))
{
if (guesses.size() == 0)
{
cout << "Sorry, make an initial guess first (all initials equivalent).";
continue;
}
int i;
if (command == 1)
{
cout << "Enter guess: ";
cin >> i;
}
else
{
cout << "Enter guess in binary: ";
i = getintfrombin();
}
memset(totals,0,sizeof(int)*(numcards+1));
for(int j = 0; j < poss->size(); j++)
{
totals[getCorrect(i,poss->at(j))]++;
}
cout << "guess = ";
printbin(i);
cout << " (" << i << ")" << endl;
for(int j = 0; j < numcards+1; j++)
{
cout << "response " << j << " = " << totals[j] << endl;
}
}
if (command == 3)
{
if (guesses.size() == 0)
{
cout << "Sorry, make an initial guess first (all initials equivalent).";
continue;
}
int limit;
cout << "Enter limit (0 for no limit): ";
cin >> limit;
if (limit > (1<<numcards)) limit = (1<<numcards);
if (limit==0) limit = (1<<numcards);
int best = 1<<numcards;
int i;
int besti=0;
for(i = 0; i < limit; i++)
{
cout << "\r" << i;
memset(totals,0,sizeof(int)*(numcards+1));
for(int j = 0; j < poss->size(); j++)
{
totals[getCorrect(i,poss->at(j))]++;
}
int max = totals[0];
for(int j = 1; j < numcards+1; j++)
{
max = max > totals[j] ? max : totals[j];
}
if (max < best)
{
best = max;
cout << endl << "guess = ";
printbin(i);
cout << " vvvvvvvvvvvvvvvvv" << endl;
for(int j = 0; j < numcards+1; j++)
{
cout << "response " << j << " = " << totals[j] << endl;
}
cout << "guess = ";
printbin(i);
cout << " ^^^^^^^^^^^^^^^^^" << "(" << i << ")" << endl;
cout << "new best!!!" << endl;
besti=i;
}
//else if (max==best)
//{
// cout << "\rguess = ";
// printbin(i);
// cout << " (" << i << ") is equivalent." << endl;
//}
}
i = besti;
memset(totals,0,sizeof(int)*(numcards+1));
for(int j = 0; j < poss->size(); j++)
{
totals[getCorrect(i,poss->at(j))]++;
}
cout << endl << "guess = ";
printbin(i);
cout << " vvvvvvvvvvvvvvvvv" << endl;
for(int j = 0; j < numcards+1; j++)
{
cout << "response " << j << " = " << totals[j] << endl;
}
cout << "guess = ";
printbin(i);
cout << " ^^^^^^^^^^^^^^^^^" << "(" << i << ")" << endl;
}
if ((command == 4) || (command == 5))
{
int guess,goal;
if (command == 4)
{
cout << "Enter guess: ";
cin >> guess;
}
else
{
cout << "Enter guess in binary: ";
guess = getintfrombin();
}
cout << "Enter response: ";
cin >> goal;
guesses.push_back(guess);
responses.push_back(goal);
if (poss->size() > 0)
{
poss = pruneit(guess,goal,poss);
}
else
{
for(int i = 0; i < 1<<numcards; i++)
{
if (getCorrect(guess,i) == goal)
{
poss->push_back(i);
}
}
}
}
if (command == 6)
{
if (guesses.size() == 0)
{
cout << "Sorry, make an initial guess first (all initials equivalent).";
continue;
}
for(int i = 0; i < poss->size(); i++)
{
printbin(poss->at(i));
cout << " (" << poss->at(i) << ")" << endl;
}
cout << endl;
}
if (command == 7)
{
cout << "Enter binary: ";
int thenum = getintfrombin();
cout << "The number is " << thenum << endl;
}
if (command == 8)
{
if (guesses.size() == 0)
{
cout << "Sorry, make an initial guess first (all initials equivalent).";
continue;
}
int best = 1<<numcards;
int i,k;
for(k = 0; k < poss->size(); k++)
{
i = poss->at(k);
cout << "\r" << (poss->size()-k);
memset(totals,0,sizeof(int)*(numcards+1));
for(int j = 0; j < poss->size(); j++)
{
totals[getCorrect(i,poss->at(j))]++;
}
int max = totals[0];
for(int j = 1; j < numcards+1; j++)
{
max = max > totals[j] ? max : totals[j];
}
if (max < best)
{
best = max;
cout << endl << "guess = ";
printbin(i);
cout << " vvvvvvvvvvvvvvvvv" << endl;
for(int j = 0; j < numcards+1; j++)
{
cout << "response " << j << " = " << totals[j] << endl;
}
cout << "guess = ";
printbin(i);
cout << " ^^^^^^^^^^^^^^^^^" << "(" << i << ")" << endl;
cout << "new best!!!" << endl;
}
}
}
}
return 0;
}