Manipulating Bit-wise Operations - bit-manipulation

There is this puzzle question of creating an equivalent bit-wise & with only | and ~ operators.
I've been doing brute force combinations of | and ~ using 6 (0110) and 5 (0101) trying to get 4 (0100), but I still cannot get the answer.
The maximum number of operation can be used is 8.
Can someone please give me hints?

What helps you here is De Morgan's Law, which basically says:
~(a & b) == ~a | ~b
Thus we can just negate this and get:
a & b == ~(~a | ~b) //4 operations
And looking at the truth table (and in fact, god bless the simplicity of binary logic, there are only four possible combintations of inputs to generate the appropriate outputs for) we can see that both are equivalent (last two columns):
a | b | ~a | ~b | ~a OR ~b | ~(~a OR ~b) | a AND b
--|---|----|----|----------|-------------|--------
0 | 0 | 1 | 1 | 1 | 0 | 0
1 | 0 | 0 | 1 | 1 | 0 | 0
0 | 1 | 1 | 0 | 1 | 0 | 0
1 | 1 | 0 | 0 | 0 | 1 | 1

Truth table time...
A B A&B !A !B !A|!B !(!A|!B)
0 0 0 1 1 1 0
0 1 0 1 0 1 0
1 0 0 0 1 1 0
1 1 1 0 0 0 1

Related

Connect IDs based on values in rows, ignoring connection between identical IDs

This is a follow-up to my previous question: Connect IDs based on values in rows.
I would now like to consider the case, where connections between identical idb's should be classified as 0.
The output is similar to the matrix in my previous post but with diagonal elements equal to 0:
62014 62015 62016 62017 62018
62014 0 1 0 1 1
62015 1 0 0 0 0
62016 0 0 0 0 1
62017 1 0 0 0 1
62018 1 0 1 1 0
How can I do this in Stata?
You can easily change the values in the diagonal of a matrix as follows:
: B
[symmetric]
1 2 3 4 5
+---------------------+
1 | 1 |
2 | 1 1 |
3 | 0 0 1 |
4 | 1 0 0 1 |
5 | 1 0 1 1 1 |
+---------------------+
: _diag(B, 0)
: B
[symmetric]
1 2 3 4 5
+---------------------+
1 | 0 |
2 | 1 0 |
3 | 0 0 0 |
4 | 1 0 0 0 |
5 | 1 0 1 1 0 |
+---------------------+
In the context of your question, you can simply do the following:
mata: B = foo1(A)
mata: _diag(B, 0)
getmata (idb*) = B
list
+------------------------------------------------------------------------+
| idb idd1 idd2 idd3 idb1 idb2 idb3 idb4 idb5 |
|------------------------------------------------------------------------|
1. | 62014 370490 879271 1112878 0 1 0 1 1 |
2. | 62015 457013 1112878 370490 1 0 0 0 0 |
3. | 62016 341863 1366174 533773 0 0 0 0 1 |
4. | 62017 879271 327069 341596 1 0 0 0 1 |
5. | 62018 1391443 1366174 879271 1 0 1 1 0 |
+------------------------------------------------------------------------+

Generate variables by many different groups

I have a dataset with:
A unique person_id.
Different subjects that the person took in the past (humanities, IT, business etc.).
The Degree of each subject.
This looks as follows:
person_id humanities business IT Degree
1 0 1 0 BSc
1 0 0 1 MSc
2 1 0 0 PhD
2 0 1 0 MSc
2 0 0 1 BSc
3 0 0 1 BSc
I would like to transform this dataset so that I have variables consisting of each possible combination of degree and subject for each person_id.
The idea is that when I collapse it later by person_id, I will have one value for each person (namely 0 or 1). I have twelve different subjects and four main degrees.
person_id humanities business IT Degree BSc_humanities MSc_Hum
1 0 1 0 BSc 0 0
1 0 0 1 MSc 0 0
2 1 0 0 PhD 0 1
2 1 0 0 MSc 0 1
2 0 0 1 BSc 0 1
3 0 0 1 BSc 0 0
What would be the best possible way to achieve this?
You could use fillin:
clear
input person_id humanities business IT str3 Degree
1 0 1 0 BSc
1 0 0 1 MSc
2 1 0 0 PhD
2 0 1 0 MSc
2 0 0 1 BSc
3 0 0 1 BSc
end
fillin person_id humanities business Degree
list person_id humanities business Degree
+-----------------------------------------+
| person~d humani~s business Degree |
|-----------------------------------------|
1. | 1 0 0 BSc |
2. | 1 0 0 MSc |
3. | 1 0 0 PhD |
4. | 1 0 1 BSc |
5. | 1 0 1 MSc |
|-----------------------------------------|
6. | 1 0 1 PhD |
7. | 1 1 0 BSc |
8. | 1 1 0 MSc |
9. | 1 1 0 PhD |
10. | 1 1 1 BSc |
|-----------------------------------------|
11. | 1 1 1 MSc |
12. | 1 1 1 PhD |
13. | 2 0 0 BSc |
14. | 2 0 0 MSc |
15. | 2 0 0 PhD |
|-----------------------------------------|
16. | 2 0 1 BSc |
17. | 2 0 1 MSc |
18. | 2 0 1 PhD |
19. | 2 1 0 BSc |
20. | 2 1 0 MSc |
|-----------------------------------------|
21. | 2 1 0 PhD |
22. | 2 1 1 BSc |
23. | 2 1 1 MSc |
24. | 2 1 1 PhD |
25. | 3 0 0 BSc |
|-----------------------------------------|
26. | 3 0 0 MSc |
27. | 3 0 0 PhD |
28. | 3 0 1 BSc |
29. | 3 0 1 MSc |
30. | 3 0 1 PhD |
|-----------------------------------------|
31. | 3 1 0 BSc |
32. | 3 1 0 MSc |
33. | 3 1 0 PhD |
34. | 3 1 1 BSc |
35. | 3 1 1 MSc |
|-----------------------------------------|
36. | 3 1 1 PhD |
+-----------------------------------------+

bit wise addtion in C++

I am looking to following code at following link
https://www.geeksforgeeks.org/divide-and-conquer-set-2-karatsuba-algorithm-for-fast-multiplication/
// The main function that adds two bit sequences and returns the addition
string addBitStrings( string first, string second )
{
string result; // To store the sum bits
// make the lengths same before adding
int length = makeEqualLength(first, second);
int carry = 0; // Initialize carry
// Add all bits one by one
for (int i = length-1 ; i >= 0 ; i--)
{
int firstBit = first.at(i) - '0';
int secondBit = second.at(i) - '0';
// boolean expression for sum of 3 bits
int sum = (firstBit ^ secondBit ^ carry)+'0';
result = (char)sum + result;
// boolean expression for 3-bit addition
carry = (firstBit&secondBit) | (secondBit&carry) | (firstBit&carry);
}
// if overflow, then add a leading 1
if (carry) result = '1' + result;
return result;
}
I am having difficulty in understanding following expressions
// boolean expression for sum of 3 bits
int sum = (firstBit ^ secondBit ^ carry)+'0';
and other expression
// boolean expression for 3-bit addition
carry = (firstBit&secondBit) | (secondBit&carry) | (firstBit&carry);
What is difference between two? What are they trying to achieve?
Thanks
To understand this, a table with all possible combinations may help. (For our luck, the number of combinations is very limited for bits.)
Starting with AND (&), OR (|), XOR (^):
a | b | a & b | a | b | a ^ b
---+---+-------+-------+-------
0 | 0 | 0 | 0 | 0
0 | 1 | 0 | 1 | 1
1 | 0 | 0 | 1 | 1
1 | 1 | 1 | 1 | 0
Putting it together:
a | b | carry | a + b + carry | a ^ b ^ carry | a & b | b & carry | a & carry | a & b | a & carry | b & carry
---+---+-------+---------------+---------------+-------+-----------+-----------+-------------------------------
0 | 0 | 0 | 00 | 0 | 0 | 0 | 0 | 0
0 | 0 | 1 | 01 | 1 | 0 | 0 | 0 | 0
0 | 1 | 0 | 01 | 1 | 0 | 0 | 0 | 0
0 | 1 | 1 | 10 | 0 | 0 | 1 | 0 | 1
1 | 0 | 0 | 01 | 1 | 0 | 0 | 0 | 0
1 | 0 | 1 | 10 | 0 | 0 | 0 | 1 | 1
1 | 1 | 0 | 10 | 0 | 1 | 0 | 0 | 1
1 | 1 | 1 | 11 | 1 | 1 | 1 | 1 | 1
Please, note, how the last digit of a + b resembles exactly the result of a ^ b ^ carry as well as a & b | a & carry | b & carry resembles the first digit of a + b.
The last detail is, adding '0' (ASCII code of digit 0) to the resp. result (0 or 1) translates this to the corresponding ASCII character ('0' or '1') again.

How to create dummies based on multiple variables

The following command can generate dummy variables:
tabulate age, generate(I)
Nevertheless, when I want a dummy based on multiple variables, what should I do?
For example, I would like to do the following concisely:
generate I1=1 if age==1 & year==2000
generate I2=1 if age==1 & year==2001
generate I3=1 if age==2 & year==2000
generate I4=1 if age==2 & year==2001
I have already tried this:
tabulate age year, generate(I)
However, it did not work.
You can get what you want as follows:
sysuse auto, clear
keep if !missing(rep78)
egen rf = group(rep78 foreign)
tabulate rf, generate(I)
group(rep78 |
foreign) | Freq. Percent Cum.
------------+-----------------------------------
1 | 2 2.90 2.90
2 | 8 11.59 14.49
3 | 27 39.13 53.62
4 | 3 4.35 57.97
5 | 9 13.04 71.01
6 | 9 13.04 84.06
7 | 2 2.90 86.96
8 | 9 13.04 100.00
------------+-----------------------------------
Total | 69 100.00
list I* in 1 / 10
+---------------------------------------+
| I1 I2 I3 I4 I5 I6 I7 I8 |
|---------------------------------------|
1. | 0 0 1 0 0 0 0 0 |
2. | 0 0 1 0 0 0 0 0 |
3. | 0 0 1 0 0 0 0 0 |
4. | 0 0 0 0 1 0 0 0 |
5. | 0 0 1 0 0 0 0 0 |
6. | 0 0 1 0 0 0 0 0 |
7. | 0 0 1 0 0 0 0 0 |
8. | 0 0 1 0 0 0 0 0 |
9. | 0 0 1 0 0 0 0 0 |
10. | 0 1 0 0 0 0 0 0 |
+---------------------------------------+

Binary AND with two false values resulting with true

Very simple question, lets say I have to values in C++ and AND them
0101 & 0110 = 0100
I want the output to be the same as a boolean equal on each value IE: 1100
This needs to be a fast as possible, as this is a low level process for a performance application. I am just getting started with bit operations, so there is probably something simple for this.
Thanks.
Basically you want a NOT(XOR(A,B))
which is in c++:
~(a^b);
Or as truth-table:
a | b | a^b | ~(a^b)
1 | 1 | 0 | 1
1 | 0 | 1 | 0
0 | 1 | 1 | 0
0 | 0 | 0 | 1