#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <assert.h>
#include <iomanip>
// demo for SO answer at http://stackoverflow.com/a/38491405/2932052
using namespace std;
const string CODE = "ATCG";
vector<unsigned> buildRMap()
{
vector<unsigned> result(256, 0);
for (size_t i=0; i<CODE.size(); ++i) {
result[CODE[i]]= i;
}
return result;
}
const vector<unsigned> RMAP = buildRMap();
enum { SEQ_LEN = 16 };
string randomDna()
{
string result(SEQ_LEN, ' ');
for (size_t i=0; i<SEQ_LEN; ++i ){
result[i] = CODE[rand() & 3];
}
return result;
}
int distS(const char* const a, const char* const b)
{
int result = 0;
for (size_t i=0; i<SEQ_LEN; ++i) {
result += a[i] != b[i];
}
return result;
}
unsigned encodeV(const string& atcg)
{
assert(atcg.size() == SEQ_LEN);
unsigned result = 0;
for (size_t i=0; i<SEQ_LEN; ++i) {
result |= RMAP[atcg[i]] << (i << 1);
}
return result;
}
int distV(const unsigned va, const unsigned vb)
{
const unsigned x = va ^ vb;
const unsigned bn = ((x & 0xaaaaaaaa) >> 1 ) | (x & 0x55555555);
return __builtin_popcount(bn);
}
int main()
{
srand(time(0));
const string a = randomDna();
const unsigned va = encodeV(a);
cout << a << " -> V: 0x" << setfill('0') << setw(8) << hex << va << endl;
const string b = randomDna();
const unsigned vb = encodeV(b);
cout << b << " -> V: 0x" << setfill('0') << setw(8) << hex << vb << endl;
cout << "dS=" << dec << distS(a.c_str(), b.c_str()) << endl;
cout << "dV=" << dec << distV(va, vb) << endl;
return 0;
}