# unique identifiers

Hi,

I need a system of making exclusive number codes. Say i have a few products, like:

hammer
drill
wedge

and then I just enumerate them:

enum {
hammer = 0,
drill,
wedge
}

how can I make a number that uniquely identifies any combination of them? Like I get the #6 and that is the combination of hammer and wedge - a zero means only a hammer, etc. I don't have any requirements, just that when I get the final number, I can decompose it into the product types that made it up.

Thanks
###### Who is Participating?

Commented:
If you have n products:

for example:

product1, product2, product3,..,productn

then you can get that unique number from formula:

product_1_used * 2^0 + product_2_used * 2^1 + product_3_used * 2^3 + ... + product_n_used * 2^(n-1)

where ^ is a power operation, and

product_i_used is 1 if product i is in group, and 0 if this is not the case.

for example if you have: hammer, drill, wedge and you need to identify set (hammer, wedge), you will get number:

hamer_used * 2^0 + drill_used * 2^1 + wedge_used * 2^2 =
1*2^0 + 0*2^1 + 1*2^2 =
1 + 0 + 4 =
5.
0

Commented:
It is also very nice, that products are numbered from 0 to n-1,

hamer_used * 2^hammer + drill_used * 2^drill + wedge_used * 2^wedge

================
On the other side, if you have an unique number k, and you want to know which tools are in group, the process is more complex but not very hard.

product_1_used = k % 2; k = k / 2;
product_2_used = k % 2; k = k / 2;
...
product_n_used  = k % 2.

where % is mod operation.

In your example, let suppose we have number 6, so: k=6,
hammer_used = 6 % 2 = 0; k = k / 2 = 3;
drill_used = 3 % 2 = 1; k =3 / 2 = 1;
wedge_used = 1 % 2 = 1;

So number 6 means that drill and wedge are used.

I will post some sample code soon.
0

Commented:
Sample code:
=============
_______________________________________________________________________________
#include <iostream>
#include <string>
using namespace std;

const int tools_num = 4;

enum Tools {
hammer = 0,
drill,            // = 1
wedge,            // = 2
screwdriver      // = 3
};

string toolName (Tools t) {
switch (t) {
case 0: return "hammer"; break;
case 1: return "drill"; break;
case 2: return "wedge"; break;
case 3: return "screwdriver"; break;
}
}

int main() {
int k;
cout << "Enter unique number: ";
cin >> k;

int tool_used[tools_num];
for (int i = 0; i < tools_num; i++) {
tool_used[i] = k % 2;
k = k / 2;
}

cout << "Tools in group: ";
for (int i = 0; i < tools_num; i++)
if (tool_used[i])
cout << toolName(Tools(i)) << " ";
cout << endl;
cin.get();
}
_______________________________________________________________________________

Sample input\output 1:
======================

__________________________________________
Enter unique number: 6
Tools in group: drill wedge
__________________________________________

Sample input\output 2:
======================

__________________________________________
Enter unique number: 15
Tools in group: hammer drill wedge screwdriver
__________________________________________

Note that probably using an enum in this case is not best idea, since you cannot automaticaly convert, Enum variable into it's string equivalent (drill (=1) into string "drill").
Maybe it is better to make an array of strings where i-th string is the name of i-th product/tool.

It is also more flexible since user can give product names and number that in this case are not limited like when using enum.

Hope this helps, Uros.
0

Commented:

enum {
hammer = 0x01,  // binary 0001
drill        = 0x02,  // binary 0010
wedge   = 0x04  // binary 0100
}

int prodnum = 6; // 0x06  or binary  0110

// use binary AND's to decompose prodnum
if (prodnum & hammer) {
// I have a hammer
}

if (prodnum & drill) {
// I have a drill
}

if (prodnum & wedge) {
// I have a wedge
}
0

Commented:
>>>> how can I make a number that uniquely identifies any combination of them?

I personally prefer using three enumerations ( if the count of objects is limited to less than 32  and if the number of (valid or used) combinations is limited as well, say less than 100:

enum {
hammer,
drill,
wedge,
max_tools   // must be last
};

Note, hammer is 0 by default and max_tools automatically counts the objects.

The following enumeration sets the corresponding bit for each tool.

enum {
HAMMER = 1 << hammer,
DRILL = 1 << drill,
WEDGE = 1 << wedge
};

With that you can write functions like that:

boolf(unsigned int usedTools)
{
// check for hammer
if (usedTools & HAMMER)
{
....
}
}

and you can call f(...) like

if ( f( WEDGE | DRILL ) )
{
...
}

If there are combinations that you want to name separatedly you could define a further enumeration:

enum ToolCombination
{
HAMMER_WEDGE = HAMMER | WEDGE,
DRILL_ONLY = DRILL,
DRILL_WEDGE = DRILL | WEDGE,
MAX_TC = 3    // unfortunately you can't count them automatically
};

const char*        allTools[max_tools] = { "hammer", "drill", "wedge", };
ToolCombination allToolCombs[MAX_TC] = {  HAMMER_WEDGE,  DRILL_ONLY,  DRILL_WEDGE, };

With that you can test whether a given combination is valid:

bool checkToolCombination(int usedTools)
{
for (int i = 0; i < MAX_TC; ++i)
if (usedTools == allToolCombs[i])
return true;

cout << "The combination of ";

for (int j = 0; j < max_tools; ++j)
if (usedTools & (1 << j))
cout << allTools[j] << " ";

cout << "is not a valid tool combination." << endl;
return false;
}

Regards, Alex

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.