easy algorithm for using flags - algorithm

Exists flags defs:
flag1=1
flag2=2
flag3=4
flag4=8
...
flagN=2^(N-1)
flag=flag1+flag2+...+flagN
if flagI not set, it eq 0
i have flag. which method can easily check, is for example flag2 defined?

Answer to your question
What's the range of flag? If it's under 2^64-1, almost every method is okay.
As #taskinoor posted, you should notice that:
flag1 = 000 ... ... 0001
flag2 = 000 ... ... 0010
flag3 = 000 ... ... 0100
In other words,
flag[n] = 1 << (n-1)
So, if you want to check all bits, a for loop and bitwise operation are fast enough to solve you problem. Like This (suppose you could understand C/C++ and flag is less than 2^32, which could be hold by an unsigned int in C/C++):
void check(unsigned int flag)
{
for (int i = 0; i < 32; ++i)
if ((flag & (1 << i)) != 0)
printf("flag%d defined!\n", i+1);
}
It's O(k), which k is the length of the type of flag in binary. For unsigned int, it's O(32) = O(1), almost in constant time.
If you just want to count how many flags defined:
I don't know what's your purpose. If you just want to count how many flags defined and flag is less than 2^64, the following method is awesome(suppose unsigned int as well):
unsigned int count_bit(unsigned int x)
{
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
x = (x & 0x0000FFFF) + ((x >> 16)& 0x0000FFFF);
return x;
}
If you call count_bit(1234567890), it'll return 12.
Let me explain this algorithm.
This algorithm is based on Divide and Conquer Algorithm. Suppose there is a 8bit integer 213(11010101 in binary), the algorithm works like this(each time merge two neighbor blocks):
+-------------------------------+
| 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | <- x
| 1 0 | 0 1 | 0 1 | 0 1 | <- first time merge
| 0 0 1 1 | 0 0 1 0 | <- second time merge
| 0 0 0 0 0 1 0 1 | <- third time ( answer = 00000101 = 5)
+-------------------------------+

Note that in each flag only one bit is set to 1, others are 0.
flag1 = 000 ... ... 0001
flag2 = 000 ... ... 0010
flag3 = 000 ... ... 0100
// and like this
So if you do bitwise AND flag & flag2 then the result will be non-zero only if flag2 is defined.
r = flag & flag2;
if r != 0 then flag2 is defined
You can do this with all flags.

Boolean isSet (flags, flagN){
Return (flags & flagN) != 0;
}
Flags being the flag vector, flagN the flag you want to check

It is worth grokking the concept of bitmasks and flags more deeply. You can then use your imagination to represent state efficiently . (Just an example explained below)
First -Define the bitmask : 0x0000001c
What are the binary strings for which when you do an 'and' operation on the mask, you get a non-zero value?
Those are your valid flag values.
Valid flag values for this bitmask: 0x0000001c,0x00000014,0x00000018,0x00000004,0x00000008,etc ..
So, in your application if you can do the following:
flagvariable |= flagvalue1 ->Enable a particular flag.
if( flagvariable & maskvalue) :Check if a mask is enabled :
Then the different cases you would need to check :
if(flagvariable &maskvalue ==flagvalue1) { do something}
else
if(flagvariable &maskvalue ==flagvalue2) {do something else}
flagvariable &= `flagvalue1 : Clear the flag
To be more clear about flags and bitmasks, just step into gdb and do p /t and evaluate the the operations described above.

Related

How can I modify bit in position in Go?

I tried to modify bit at a certain position, but ran into a problem.
For example I have 1000000001, how can I modify it to 0000000001?
You can apply a bitmask to only keep the bits you are interested in.
In this case if you only want the last bit, you apply the bitmask 0b0000000001
https://go.dev/play/p/RNQEcON7sw1
// 'x' is your value
x := 0b1000000001
// Make the bitmask
mask := 0b0000000001
// Apply the bitmask with bitwise AND
output := x&mask
fmt.Println("This value == 1: ", output)
Explaination
& is a bitwise operator for "AND". Which means it goes through both values bit by bit and sets the resulting bit to 1 if and only if both input bits are 1. I included a truth table for the AND operator below.
+-----------+----------+--------------+
| Input Bit | Mask Bit | Input & Mask |
+-----------+----------+--------------+
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
+-----------+----------+--------------+
Because my mask function only has a 1 in the last position, only the last position of the original input is kept. All preceding bits will always be 0.
Construct a mask that has a one in every place you want to manipulate
Use bitwise OR to set bits.
Use bitwise AND with the inverse mask to clear bits.
Use XOR to toggle a bits
package main
import "fmt"
func main() {
k := 3 // manipulate the 3rd bit ...
mask := uint8(1) << (k - 1) // ... using 0b00000100 as a mask
var n uint8 = 0b10101010
fmt.Printf("0b%08b\n", n) // 0b10101010
// set kth bit
n |= mask
fmt.Printf("0b%08b\n", n) // 0b10101110
// clear kth bit
n &^= mask // &^ is Go's AND NOT operator
fmt.Printf("0b%08b\n", n) // 0b10101010
// toggle kth bit
n ^= mask
fmt.Printf("0b%08b\n", n) // 0b10101110
}
func test() {
i := 1 << 9 //1000000000
i = i | (1 << 8) //1000000000 | 0100000000 == 1100000000
i = i | (1 << 7) //1100000000 | 0010000000 == 1110000000
i = i | (1 << 0) //1110000000 | 0000000001 == 1110000001
fmt.Printf("BEFORE: %010b\n", i) // 1110000001
i = i & ((1 << 9) - 1) // 1110000001 & ((1000000000) - 1) == 1110000001 & (0111111111) == 0110000001
fmt.Printf("AFTER: %010b\n", i) // 0110000001
}

Find the closest integer with same weight O(1)

I am solving this problem:
The count of ones in binary representation of integer number is called the weight of that number. The following algorithm finds the closest integer with the same weight. For example, for 123 (0111 1011)₂, the closest integer number is 125 (0111 1101)₂.
The solution for O(n)
where n is the width of the input number is by swapping the positions of the first pair of consecutive bits that differ.
Could someone give me some hints for solving in it in O(1) runtime and space ?
Thanks
As already commented by ajayv this cannot really be done in O(1) as the answer always depends on the number of bits the input has. However, if we interpret the O(1) to mean that we have as an input some primitive integer data and all the logic and arithmetic operations we perform on that integer are O(1) (no loops over the bits), the problem can be solved in constant time. Of course, if we changed from 32bit integer to 64bit integer the running time would increase as the arithmetic operations would take longer on hardware.
One possible solution is to use following functions. The first gives you a number where only the lowest set bit of x is set
int lowestBitSet(int x){
( x & ~(x-1) )
}
and the second the lowest bit not set
int lowestBitNotSet(int x){
return ~x & (x+1);
}
If you work few examples of these on paper you see how they work.
Now you can find the bits you need to change using these two functions and then use the algorithm you already described.
A c++ implementation (not checking for cases where there are no answer)
unsigned int closestInt(unsigned int x){
unsigned int ns=lowestBitNotSet(x);
unsigned int s=lowestBitSet(x);
if (ns>s){
x|=ns;
x^=ns>>1;
}
else{
x^=s;
x|=s>>1;
}
return x;
}
To solve this problem in O(1) time complexity it can be considered that there are two main cases:
1) When LSB is '0':
In this case, the first '1' must be shifted with one position to the right.
Input : "10001000"
Out ::: "10000100"
2) When LSB is '1':
In this case the first '0' must be set to '1', and first '1' must be set to '0'.
Input : "10000111"
Out ::: "10001110"
The next method in Java represents one solution.
private static void findClosestInteger(String word) { // ex: word = "10001000"
System.out.println(word); // Print initial binary format of the number
int x = Integer.parseInt(word, 2); // Convert String to int
if((x & 1) == 0) { // Evaluates LSB value
// Case when LSB = '0':
// Input: x = 10001000
int firstOne = x & ~(x -1); // get first '1' position (from right to left)
// firstOne = 00001000
x = x & (x - 1); // set first '1' to '0'
// x = 10000000
x = x | (firstOne >> 1); // "shift" first '1' with one position to right
// x = 10000100
} else {
// Case when LSB = '1':
// Input: x = 10000111
int firstZero = ~x & ~(~x - 1); // get first '0' position (from right to left)
// firstZero = 00001000
x = x & (~1); // set first '1', which is the LSB, to '0'
// x = 10000110
x = x | firstZero; // set first '0' to '1'
// x = 10001110
}
for(int i = word.length() - 1; i > -1 ; i--) { // print the closest integer with same weight
System.out.print("" + ( ( (x & 1 << i) != 0) ? 1 : 0) );
}
}
The problem can be viewed as "which differing bits to swap in a bit representation of a number, so that the resultant number is closest to the original?"
So, if we we're to swap bits at indices k1 & k2, with k2 > k1, the difference between the numbers would be 2^k2 - 2^k1. Our goal is to minimize this difference. Assuming that the bit representation is not all 0s or all 1s, a simple observation yields that the difference would be least if we kept |k2 - k1| as minimum. The minimum value can be 1. So, if we're able to find two consecutive different bits, starting from the least significant bit (index = 0), our job is done.
The case where bits starting from Least Significant Bit to the right most set bit are all 1s
k2
|
7 6 5 4 3 2 1 0
---------------
n: 1 1 1 0 1 0 1 1
rightmostSetBit: 0 0 0 0 0 0 0 1
rightmostNotSetBit: 0 0 0 0 0 1 0 0 rightmostNotSetBit > rightmostSetBit so,
difference: 0 0 0 0 0 0 1 0 i.e. rightmostNotSetBit - (rightmostNotSetBit >> 1):
---------------
n + difference: 1 1 1 0 1 1 0 1
The case where bits starting from Least Significant Bit to the right most set bit are all 0s
k2
|
7 6 5 4 3 2 1 0
---------------
n: 1 1 1 0 1 1 0 0
rightmostSetBit: 0 0 0 0 0 1 0 0
rightmostNotSetBit: 0 0 0 0 0 0 0 1 rightmostSetBit > rightmostNotSetBit so,
difference: 0 0 0 0 0 0 1 0 i.e. rightmostSetBit -(rightmostSetBit>> 1)
---------------
n - difference: 1 1 1 0 1 0 1 0
The edge case, of course the situation where we have all 0s or all 1s.
public static long closestToWeight(long n){
if(n <= 0 /* If all 0s */ || (n+1) == Integer.MIN_VALUE /* n is MAX_INT */)
return -1;
long neg = ~n;
long rightmostSetBit = n&~(n-1);
long rightmostNotSetBit = neg&~(neg-1);
if(rightmostNotSetBit > rightmostSetBit){
return (n + (rightmostNotSetBit - (rightmostNotSetBit >> 1)));
}
return (n - (rightmostSetBit - (rightmostSetBit >> 1)));
}
Attempted the problem in Python. Can be viewed as a translation of Ari's solution with the edge case handled:
def closest_int_same_bit_count(x):
# if all bits of x are 0 or 1, there can't be an answer
if x & sys.maxsize in {sys.maxsize, 0}:
raise ValueError("All bits are 0 or 1")
rightmost_set_bit = x & ~(x - 1)
next_un_set_bit = ~x & (x + 1)
if next_un_set_bit > rightmost_set_bit:
# 0 shifted to the right e.g 0111 -> 1011
x ^= next_un_set_bit | next_un_set_bit >> 1
else:
# 1 shifted to the right 1000 -> 0100
x ^= rightmost_set_bit | rightmost_set_bit >> 1
return x
Similarly jigsawmnc's solution is provided below:
def closest_int_same_bit_count(x):
# if all bits of x are 0 or 1, there can't be an answer
if x & sys.maxsize in {sys.maxsize, 0}:
raise ValueError("All bits are 0 or 1")
rightmost_set_bit = x & ~(x - 1)
next_un_set_bit = ~x & (x + 1)
if next_un_set_bit > rightmost_set_bit:
# 0 shifted to the right e.g 0111 -> 1011
x += next_un_set_bit - (next_un_set_bit >> 1)
else:
# 1 shifted to the right 1000 -> 0100
x -= rightmost_set_bit - (rightmost_set_bit >> 1)
return x
Java Solution:
//Swap the two rightmost consecutive bits that are different
for (int i = 0; i < 64; i++) {
if ((((x >> i) & 1) ^ ((x >> (i+1)) & 1)) == 1) {
// then swap them or flip their bits
int mask = (1 << i) | (1 << i + 1);
x = x ^ mask;
System.out.println("x = " + x);
return;
}
}
static void findClosestIntWithSameWeight(uint x)
{
uint xWithfirstBitSettoZero = x & (x - 1);
uint xWithOnlyfirstbitSet = x & ~(x - 1);
uint xWithNextTofirstBitSet = xWithOnlyfirstbitSet >> 1;
uint closestWeightNum = xWithfirstBitSettoZero | xWithNextTofirstBitSet;
Console.WriteLine("Closet Weight for {0} is {1}", x, closestWeightNum);
}
Code in python:
def closest_int_same_bit_count(x):
if (x & 1) != ((x >> 1) & 1):
return x ^ 0x3
diff = x ^ (x >> 1)
rbs = diff & ~(diff - 1)
i = int(math.log(rbs, 2))
return x ^ (1 << i | 1 << i + 1)
A great explanation of this problem can be found on question 4.4 in EPI.
(Elements of Programming Interviews)
Another place would be this link on geeksforgeeks.org if you don't own the book.
(Time complexity may be wrong on this link)
Two things you should keep in mind here is (Hint if you're trying to solve this for yourself):
You can use x & (x - 1) to clear the lowest set-bit (not to get confused with LSB - least significant bit)
You can use x & ~(x - 1) to get/extract the lowest set bit
If you know the O(n) solution you know that we need to find the index of the first bit that differs from LSB.
If you don't know what the LBS is:
0000 0000
^ // it's bit all the way to the right of a binary string.
Take the base two number 1011 1000 (184 in decimal)
The first bit that differs from LSB:
1011 1000
^ // this one
We'll record this as K1 = 0000 1000
Then we need to swap it with the very next bit to the right:
0000 1000
^ // this one
We'll record this as K2 = 0000 0100
Bitwise OR K1 and K2 together and you'll get a mask
mask = K1 | k2 // 0000 1000 | 0000 0100 -> 0000 1100
Bitwise XOR the mask with the original number and you'll have the correct output/swap
number ^ mask // 1011 1000 ^ 0000 1100 -> 1011 0100
Now before we pull everything together we have to consider that fact that the LSB could be 0001, and so could a bunch of bits after that 1000 1111. So we have to deal with the two cases of the first bit that differs from the LSB; it may be a 1 or 0.
First we have a conditional that test the LSB to be 1 or 0: x & 1
IF 1 return x XORed with the return of a helper function
This helper function has a second argument which its value depends on whether the condition is true or not. func(x, 0xFFFFFFFF) // if true // 0xFFFFFFFF 64 bit word with all bits set to 1
Otherwise we'll skip the if statement and return a similar expression but with a different value provided to the second argument.
return x XORed with func(x, 0x00000000) // 64 bit word with all bits set to 0. You could alternatively just pass 0 but I did this for consistency
Our helper function returns a mask that we are going to XOR with the original number to get our output.
It takes two arguments, our original number and a mask, used in this expression:
(x ^ mask) & ~((x ^ mask) - 1)
which gives us a new number with the bit at index K1 always set to 1.
It then shifts that bit 1 to the right (i.e index K2) then ORs it with itself to create our final mask
0000 1000 >> 1 -> 0000 0100 | 0001 0000 -> 0000 1100
This all implemented in C++ looks like:
unsigned long long int closestIntSameBitCount(unsigned long long int n)
{
if (n & 1)
return n ^= getSwapMask(n, 0xFFFFFFFF);
return n ^= getSwapMask(n, 0x00000000);
}
// Helper function
unsigned long long int getSwapMask(unsigned long long int n, unsigned long long int mask)
{
unsigned long long int swapBitMask = (n ^ mask) & ~((n ^ mask) - 1);
return swapBitMask | (swapBitMask >> 1);
}
Keep note of the expression (x ^ mask) & ~((x ^ mask) - 1)
I'll now run through this code with my example 1011 1000:
// start of closestIntSameBitCount
if (0) // 1011 1000 & 1 -> 0000 0000
// start of getSwapMask
getSwapMask(1011 1000, 0x00000000)
swapBitMask = (x ^ mask) & ~1011 0111 // ((x ^ mask) - 1) = 1011 1000 ^ .... 0000 0000 -> 1011 1000 - 1 -> 1011 0111
swapBitMask = (x ^ mask) & 0100 1000 // ~1011 0111 -> 0100 1000
swapBitMask = 1011 1000 & 0100 1000 // (x ^ mask) = 1011 1000 ^ .... 0000 0000 -> 1011 1000
swapBitMask = 0000 1000 // 1011 1000 & 0100 1000 -> 0000 1000
return swapBitMask | 0000 0100 // (swapBitMask >> 1) = 0000 1000 >> 1 -> 0000 0100
return 0000 1100 // 0000 1000 | 0000 0100 -> 0000 11000
// end of getSwapMask
return 1011 0100 // 1011 1000 ^ 0000 11000 -> 1011 0100
// end of closestIntSameBitCount
Here is a full running example if you would like compile and run it your self:
#include <iostream>
#include <stdio.h>
#include <bitset>
unsigned long long int closestIntSameBitCount(unsigned long long int n);
unsigned long long int getSwapMask(unsigned long long int n, unsigned long long int mask);
int main()
{
unsigned long long int number;
printf("Pick a number: ");
std::cin >> number;
std::bitset<64> a(number);
std::bitset<64> b(closestIntSameBitCount(number));
std::cout << a
<< "\n"
<< b
<< std::endl;
}
unsigned long long int closestIntSameBitCount(unsigned long long int n)
{
if (n & 1)
return n ^= getSwapMask(n, 0xFFFFFFFF);
return n ^= getSwapMask(n, 0x00000000);
}
// Helper function
unsigned long long int getSwapMask(unsigned long long int n, unsigned long long int mask)
{
unsigned long long int swapBitMask = (n ^ mask) & ~((n ^ mask) - 1);
return swapBitMask | (swapBitMask >> 1);
}
This was my solution to the problem. I guess #jigsawmnc explains pretty well why we need to have |k2 -k1| to a minimum. So in order to find the closest integer, with the same weight, we would want to find the location where consecutive bits are flipped and then flip them again to get the answer. In order to do that we can shift the number 1 unit. Take the XOR with the same number. This will set bits at all locations where there is a flip. Find the least significant bit for the XOR. This will give you the smallest location to flip. Create a mask for the location and next bit. Take an XOR and that should be the answer. This won't work, if the digits are all 0 or all 1
Here is the code for it.
def variant_closest_int(x: int) -> int:
if x == 0 or ~x == 0:
raise ValueError('All bits are 0 or 1')
x_ = x >> 1
lsb = x ^ x_
mask_ = lsb & ~(lsb - 1)
mask = mask_ | (mask_ << 1)
return x ^ mask
My solution, takes advantage of the parity of the integer. I think the way I got the LSB masks can be simplified
def next_weighted_int(x):
if x % 2 == 0:
lsb_mask = ( ((x - 1) ^ x) >> 1 ) + 1 # Gets a mask for the first 1
x ^= lsb_mask
x |= (lsb_mask >> 1)
return x
lsb_mask = ((x ^ (x + 1)) >> 1 ) + 1 # Gets a mask for the first 0
x |= lsb_mask
x ^= (lsb_mask >> 1)
return x
Just sharing my python solution for this problem:
def same closest_int_same_bit_count(a):
x = a + (a & 1) # change last bit to 0
bit = (x & ~(x-1)) # get last set bit
return a ^ (bit | bit >> 1) # swap set bit with unset bit
func findClosestIntegerWithTheSameWeight2(x int) int {
rightMost0 := ^x & (x + 1)
rightMost1 := x & (-x)
if rightMost0 > 1 {
return (x ^ rightMost0) ^ (rightMost0 >> 1)
} else {
return (x ^ rightMost1) ^ (rightMost1 >> 1)
}
}

How to get lg2 of a number that is 2^k

What is the best solution for getting the base 2 logarithm of a number that I know is a power of two (2^k). (Of course I know only the value 2^k not k itself.)
One way I thought of doing is by subtracting 1 and then doing a bitcount:
lg2(n) = bitcount( n - 1 ) = k, iff k is an integer
0b10000 - 1 = 0b01111, bitcount(0b01111) = 4
But is there a faster way of doing it (without caching)? Also something that doesn't involve bitcount about as fast would be nice to know?
One of the applications this is:
suppose you have bitmask
0b0110111000
and value
0b0101010101
and you are interested of
(value & bitmask) >> number of zeros in front of bitmask
(0b0101010101 & 0b0110111000) >> 3 = 0b100010
this can be done with
using bitcount
value & bitmask >> bitcount((bitmask - 1) xor bitmask) - 1
or using lg2
value & bitmask >> lg2(((bitmask - 1) xor bitmask) + 1 ) - 2
For it to be faster than bitcount without caching it should be faster than O(lg(k)) where k is the count of storage bits.
Yes. Here's a way to do it without the bitcount in lg(n), if you know the integer in question is a power of 2.
unsigned int x = ...;
static const unsigned int arr[] = {
// Each element in this array alternates a number of 1s equal to
// consecutive powers of two with an equal number of 0s.
0xAAAAAAAA, // 0b10101010.. // one 1, then one 0, ...
0xCCCCCCCC, // 0b11001100.. // two 1s, then two 0s, ...
0xF0F0F0F0, // 0b11110000.. // four 1s, then four 0s, ...
0xFF00FF00, // 0b1111111100000000.. // [The sequence continues.]
0xFFFF0000
}
register unsigned int reg = (x & arr[0]) != 0;
reg |= ((x & arr[4]) != 0) << 4;
reg |= ((x & arr[3]) != 0) << 3;
reg |= ((x & arr[2]) != 0) << 2;
reg |= ((x & arr[1]) != 0) << 1;
// reg now has the value of lg(x).
In each of the reg |= steps, we successively test to see if any of the bits of x are shared with alternating bitmasks in arr. If they are, that means that lg(x) has bits which are in that bitmask, and we effectively add 2^k to reg, where k is the log of the length of the alternating bitmask. For example, 0xFF00FF00 is an alternating sequence of 8 ones and zeroes, so k is 3 (or lg(8)) for this bitmask.
Essentially, each reg |= ((x & arr[k]) ... step (and the initial assignment) tests whether lg(x) has bit k set. If so, we add it to reg; the sum of all those bits will be lg(x).
That looks like a lot of magic, so let's try an example. Suppose we want to know what power of 2 the value 2,048 is:
// x = 2048
// = 1000 0000 0000
register unsigned int reg = (x & arr[0]) != 0;
// reg = 1000 0000 0000
& ... 1010 1010 1010
= 1000 0000 0000 != 0
// reg = 0x1 (1) // <-- Matched! Add 2^0 to reg.
reg |= ((x & arr[4]) != 0) << 4;
// reg = 0x .. 0800
& 0x .. 0000
= 0 != 0
// reg = reg | (0 << 4) // <--- No match.
// reg = 0x1 | 0
// reg remains 0x1.
reg |= ((x & arr[3]) != 0) << 3;
// reg = 0x .. 0800
& 0x .. FF00
= 800 != 0
// reg = reg | (1 << 3) // <--- Matched! Add 2^3 to reg.
// reg = 0x1 | 0x8
// reg is now 0x9.
reg |= ((x & arr[2]) != 0) << 2;
// reg = 0x .. 0800
& 0x .. F0F0
= 0 != 0
// reg = reg | (0 << 2) // <--- No match.
// reg = 0x9 | 0
// reg remains 0x9.
reg |= ((x & arr[1]) != 0) << 1;
// reg = 0x .. 0800
& 0x .. CCCC
= 800 != 0
// reg = reg | (1 << 1) // <--- Matched! Add 2^1 to reg.
// reg = 0x9 | 0x2
// reg is now 0xb (11).
We see that the final value of reg is 2^0 + 2^1 + 2^3, which is indeed 11.
If you know the number is a power of 2, you could just shift it right (>>) until it equals 0. The amount of times you shifted right (minus 1) is your k.
Edit: faster than this is the lookup table method (though you sacrifice some space, but not a ton). See http://doctorinterview.com/index.html/algorithmscoding/find-the-integer-log-base-2-of-an-integer/.
Many architectures have a "find first one" instruction (bsr, clz, bfffo, cntlzw, etc.) which will be much faster than bit-counting approaches.
If you don't mind dealing with floats you can use log(x) / log(2).

How can I generate this pattern of numbers?

Given inputs 1-32 how can I generate the below output?
in. out
1
1
1
1
2
2
2
2
1
1
1
1
2
2
2
2
...
Edit Not Homework.. just lack of sleep.
I am working in C#, but I was looking for a language agnostic algorithm.
Edit 2 To provide a bit more background... I have an array of 32 items that represents a two dimensional checkerboard. I needed the last part of this algorithm to convert between the vector and the graph, where the index aligns on the black squares on the checkerboard.
Final Code:
--Index;
int row = Index >> 2;
int col = 2 * Index - (((Index & 0x04) >> 2 == 1) ? 2 : 1);
Assuming that you can use bitwise operators you can check what the numbers with same output have in common, in this case I preferred using input 0-31 because it's simpler (you can just subtract 1 to actual values)
What you have?
0x0000 -> 1
0x0001 -> 1
0x0010 -> 1
0x0011 -> 1
0x0100 -> 2
0x0101 -> 2
0x0110 -> 2
0x0111 -> 2
0x1000 -> 1
0x1001 -> 1
0x1010 -> 1
0x1011 -> 1
0x1100 -> 2
...
It's quite easy if you notice that third bit is always 0 when output should be 1 and viceversa it's always 1 when output should be 2
so:
char codify(char input)
{
return ((((input-1)&0x04)>>2 == 1)?(2):(1));
}
EDIT
As suggested by comment it should work also with
char codify(char input)
{
return ((input-1 & 0x04)?(2):(1));
}
because in some languages (like C) 0 will evaluate to false and any other value to true. I'm not sure if it works in C# too because I've never programmed in that language. Of course this is not a language-agnostic answer but it's more C-elegant!
in C:
char output = "11112222"[input-1 & 7];
or
char output = (input-1 >> 2 & 1) + '1';
or after an idea of FogleBird:
char output = input - 1 & 4 ? '2' : '1';
or after an idea of Steve Jessop:
char output = '2' - (0x1e1e1e1e >> input & 1);
or
char output = "12"[input-1>>2&1];
C operator precedence is evil. Do use my code as bad examples :-)
You could use a combination of integer division and modulo 2 (even-odd): There are blocks of four, and the 1st, 3rd, 5th block and so on should result in 1, the 2nd, 4th, 6th and so on in 2.
s := ((n-1) div 4) mod 2;
return s + 1;
div is supposed to be integer division.
EDIT: Turned first mod into a div, of course
Just for laughs, here's a technique that maps inputs 1..32 to two possible outputs, in any arbitrary way known at compile time:
// binary 1111 0000 1111 0000 1111 0000 1111 0000
const uint32_t lu_table = 0xF0F0F0F0;
// select 1 bit out of the table
if (((1 << (input-1)) & lu_table) == 0) {
return 1;
} else {
return 2;
}
By changing the constant, you can handle whatever pattern of outputs you want. Obviously in your case there's a pattern which means it can probably be done faster (since no shift is needed), but everyone else already did that. Also, it's more common for a lookup table to be an array, but that's not necessary here.
The accepted answer return ((((input-1)&0x04)>>2 == 1)?(2):(1)); uses a branch while I would have just written:
return 1 + ((input-1) & 0x04 ) >> 2;
Python
def f(x):
return int((x - 1) % 8 > 3) + 1
Or:
def f(x):
return 2 if (x - 1) & 4 else 1
Or:
def f(x):
return (((x - 1) & 4) >> 2) + 1
In Perl:
#!/usr/bin/perl
use strict; use warnings;
sub it {
return sub {
my ($n) = #_;
return 1 if 4 > ($n - 1) % 8;
return 2;
}
}
my $it = it();
for my $x (1 .. 32) {
printf "%2d:%d\n", $x, $it->($x);
}
Or:
sub it {
return sub {
my ($n) = #_;
use integer;
return 1 + ( (($n - 1) / 4) % 2 );
}
}
In Haskell:
vec2graph :: Int -> Char
vec2graph n = (cycle "11112222") !! (n-1)
Thats pretty straightforward:
if (input == "1") {Console.WriteLine(1)};
if (input == "2") {Console.WriteLine(1)};
if (input == "3") {Console.WriteLine(1)};
if (input == "4") {Console.WriteLine(1)};
if (input == "5") {Console.WriteLine(2)};
if (input == "6") {Console.WriteLine(2)};
if (input == "7") {Console.WriteLine(2)};
if (input == "8") {Console.WriteLine(2)};
etc...
HTH
It depends of the language you are using.
In VB.NET, you could do something like this :
for i as integer = 1 to 32
dim intAnswer as integer = 1 + (Math.Floor((i-1) / 4) mod 2)
' Do whatever you need to do with it
next
It might sound complicated, but it's only because I put it into a sigle line.
In Groovy:
def codify = { i ->
return (((((i-1)/4).intValue()) %2 ) + 1)
}
Then:
def list = 1..16
list.each {
println "${it}: ${codify(it)}"
}
char codify(char input)
{
return (((input-1) & 0x04)>>2) + 1;
}
Using Python:
output = 1
for i in range(1, 32+1):
print "%d. %d" % (i, output)
if i % 4 == 0:
output = output == 1 and 2 or 1
JavaScript
My first thought was
output = ((input - 1 & 4) >> 2) + 1;
but drhirsch's code works fine in JavaScript:
output = input - 1 & 4 ? 2 : 1;
and the ridiculous (related to FogleBird's answer):
output = -~((input - 1) % 8 > 3);
Java, using modulo operation ('%') to give the cyclic behaviour (0,1,2...7) and then a ternary if to 'round' to 1(?) or 2(:) depending on returned value.
...
public static void main(String[] args) {
for (int i=1;i<=32;i++) {
System.out.println(i+"="+ (i%8<4?1:2) );
}
Produces:
1=1 2=1 3=1 4=2 5=2 6=2 7=2 8=1 9=1
10=1 11=1 12=2 13=2 14=2 15=2 16=1
17=1 18=1 19=1 20=2 21=2 22=2 23=2
24=1 25=1 26=1 27=1 28=2 29=2 30=2
31=2 32=1

Counting, reversed bit pattern

I am trying to find an algorithm to count from 0 to 2n-1 but their bit pattern reversed. I care about only n LSB of a word. As you may have guessed I failed.
For n=3:
000 -> 0
100 -> 4
010 -> 2
110 -> 6
001 -> 1
101 -> 5
011 -> 3
111 -> 7
You get the idea.
Answers in pseudo-code is great. Code fragments in any language are welcome, answers without bit operations are preferred.
Please don't just post a fragment without even a short explanation or a pointer to a source.
Edit: I forgot to add, I already have a naive implementation which just bit-reverses a count variable. In a sense, this method is not really counting.
This is, I think easiest with bit operations, even though you said this wasn't preferred
Assuming 32 bit ints, here's a nifty chunk of code that can reverse all of the bits without doing it in 32 steps:
unsigned int i;
i = (i & 0x55555555) << 1 | (i & 0xaaaaaaaa) >> 1;
i = (i & 0x33333333) << 2 | (i & 0xcccccccc) >> 2;
i = (i & 0x0f0f0f0f) << 4 | (i & 0xf0f0f0f0) >> 4;
i = (i & 0x00ff00ff) << 8 | (i & 0xff00ff00) >> 8;
i = (i & 0x0000ffff) << 16 | (i & 0xffff0000) >> 16;
i >>= (32 - n);
Essentially this does an interleaved shuffle of all of the bits. Each time around half of the bits in the value are swapped with the other half.
The last line is necessary to realign the bits so that bin "n" is the most significant bit.
Shorter versions of this are possible if "n" is <= 16, or <= 8
At each step, find the leftmost 0 digit of your value. Set it, and clear all digits to the left of it. If you don't find a 0 digit, then you've overflowed: return 0, or stop, or crash, or whatever you want.
This is what happens on a normal binary increment (by which I mean it's the effect, not how it's implemented in hardware), but we're doing it on the left instead of the right.
Whether you do this in bit ops, strings, or whatever, is up to you. If you do it in bitops, then a clz (or call to an equivalent hibit-style function) on ~value might be the most efficient way: __builtin_clz where available. But that's an implementation detail.
This solution was originally in binary and converted to conventional math as the requester specified.
It would make more sense as binary, at least the multiply by 2 and divide by 2 should be << 1 and >> 1 for speed, the additions and subtractions probably don't matter one way or the other.
If you pass in mask instead of nBits, and use bitshifting instead of multiplying or dividing, and change the tail recursion to a loop, this will probably be the most performant solution you'll find since every other call it will be nothing but a single add, it would only be as slow as Alnitak's solution once every 4, maybe even 8 calls.
int incrementBizarre(int initial, int nBits)
// in the 3 bit example, this should create 100
mask=2^(nBits-1)
// This should only return true if the first (least significant) bit is not set
// if initial is 011 and mask is 100
// 3 4, bit is not set
if(initial < mask)
// If it was not, just set it and bail.
return initial+ mask // 011 (3) + 100 (4) = 111 (7)
else
// it was set, are we at the most significant bit yet?
// mask 100 (4) / 2 = 010 (2), 001/2 = 0 indicating overflow
if(mask / 2) > 0
// No, we were't, so unset it (initial-mask) and increment the next bit
return incrementBizarre(initial - mask, mask/2)
else
// Whoops we were at the most significant bit. Error condition
throw new OverflowedMyBitsException()
Wow, that turned out kinda cool. I didn't figure in the recursion until the last second there.
It feels wrong--like there are some operations that should not work, but they do because of the nature of what you are doing (like it feels like you should get into trouble when you are operating on a bit and some bits to the left are non-zero, but it turns out you can't ever be operating on a bit unless all the bits to the left are zero--which is a very strange condition, but true.
Example of flow to get from 110 to 001 (backwards 3 to backwards 4):
mask 100 (4), initial 110 (6); initial < mask=false; initial-mask = 010 (2), now try on the next bit
mask 010 (2), initial 010 (2); initial < mask=false; initial-mask = 000 (0), now inc the next bit
mask 001 (1), initial 000 (0); initial < mask=true; initial + mask = 001--correct answer
Here's a solution from my answer to a different question that computes the next bit-reversed index without looping. It relies heavily on bit operations, though.
The key idea is that incrementing a number simply flips a sequence of least-significant bits, for example from nnnn0111 to nnnn1000. So in order to compute the next bit-reversed index, you have to flip a sequence of most-significant bits. If your target platform has a CTZ ("count trailing zeros") instruction, this can be done efficiently.
Example in C using GCC's __builtin_ctz:
void iter_reversed(unsigned bits) {
unsigned n = 1 << bits;
for (unsigned i = 0, j = 0; i < n; i++) {
printf("%x\n", j);
// Compute a mask of LSBs.
unsigned mask = i ^ (i + 1);
// Length of the mask.
unsigned len = __builtin_ctz(~mask);
// Align the mask to MSB of n.
mask <<= bits - len;
// XOR with mask.
j ^= mask;
}
}
Without a CTZ instruction, you can also use integer division:
void iter_reversed(unsigned bits) {
unsigned n = 1 << bits;
for (unsigned i = 0, j = 0; i < n; i++) {
printf("%x\n", j);
// Find least significant zero bit.
unsigned bit = ~i & (i + 1);
// Using division to bit-reverse a single bit.
unsigned rev = (n / 2) / bit;
// XOR with mask.
j ^= (n - 1) & ~(rev - 1);
}
}
void reverse(int nMaxVal, int nBits)
{
int thisVal, bit, out;
// Calculate for each value from 0 to nMaxVal.
for (thisVal=0; thisVal<=nMaxVal; ++thisVal)
{
out = 0;
// Shift each bit from thisVal into out, in reverse order.
for (bit=0; bit<nBits; ++bit)
out = (out<<1) + ((thisVal>>bit) & 1)
}
printf("%d -> %d\n", thisVal, out);
}
Maybe increment from 0 to N (the "usual" way") and do ReverseBitOrder() for each iteration. You can find several implementations here (I like the LUT one the best).
Should be really quick.
Here's an answer in Perl. You don't say what comes after the all ones pattern, so I just return zero. I took out the bitwise operations so that it should be easy to translate into another language.
sub reverse_increment {
my($n, $bits) = #_;
my $carry = 2**$bits;
while($carry > 1) {
$carry /= 2;
if($carry > $n) {
return $carry + $n;
} else {
$n -= $carry;
}
}
return 0;
}
Here's a solution which doesn't actually try to do any addition, but exploits the on/off pattern of the seqence (most sig bit alternates every time, next most sig bit alternates every other time, etc), adjust n as desired:
#define FLIP(x, i) do { (x) ^= (1 << (i)); } while(0)
int main() {
int n = 3;
int max = (1 << n);
int x = 0;
for(int i = 1; i <= max; ++i) {
std::cout << x << std::endl;
/* if n == 3, this next part is functionally equivalent to this:
*
* if((i % 1) == 0) FLIP(x, n - 1);
* if((i % 2) == 0) FLIP(x, n - 2);
* if((i % 4) == 0) FLIP(x, n - 3);
*/
for(int j = 0; j < n; ++j) {
if((i % (1 << j)) == 0) FLIP(x, n - (j + 1));
}
}
}
How about adding 1 to the most significant bit, then carrying to the next (less significant) bit, if necessary. You could speed this up by operating on bytes:
Precompute a lookup table for counting in bit-reverse from 0 to 256 (00000000 -> 10000000, 10000000 -> 01000000, ..., 11111111 -> 00000000).
Set all bytes in your multi-byte number to zero.
Increment the most significant byte using the lookup table. If the byte is 0, increment the next byte using the lookup table. If the byte is 0, increment the next byte...
Go to step 3.
With n as your power of 2 and x the variable you want to step:
(defun inv-step (x n) ; the following is a function declaration
"returns a bit-inverse step of x, bounded by 2^n" ; documentation
(do ((i (expt 2 (- n 1)) ; loop, init of i
(/ i 2)) ; stepping of i
(s x)) ; init of s as x
((not (integerp i)) ; breaking condition
s) ; returned value if all bits are 1 (is 0 then)
(if (< s i) ; the loop's body: if s < i
(return-from inv-step (+ s i)) ; -> add i to s and return the result
(decf s i)))) ; else: reduce s by i
I commented it thoroughly as you may not be familiar with this syntax.
edit: here is the tail recursive version. It seems to be a little faster, provided that you have a compiler with tail call optimization.
(defun inv-step (x n)
(let ((i (expt 2 (- n 1))))
(cond ((= n 1)
(if (zerop x) 1 0)) ; this is really (logxor x 1)
((< x i)
(+ x i))
(t
(inv-step (- x i) (- n 1))))))
When you reverse 0 to 2^n-1 but their bit pattern reversed, you pretty much cover the entire 0-2^n-1 sequence
Sum = 2^n * (2^n+1)/2
O(1) operation. No need to do bit reversals
Edit: Of course original poster's question was about to do increment by (reversed) one, which makes things more simple than adding two random values. So nwellnhof's answer contains the algorithm already.
Summing two bit-reversal values
Here is one solution in php:
function RevSum ($a,$b) {
// loop until our adder, $b, is zero
while ($b) {
// get carry (aka overflow) bit for every bit-location by AND-operation
// 0 + 0 --> 00 no overflow, carry is "0"
// 0 + 1 --> 01 no overflow, carry is "0"
// 1 + 0 --> 01 no overflow, carry is "0"
// 1 + 1 --> 10 overflow! carry is "1"
$c = $a & $b;
// do 1-bit addition for every bit location at once by XOR-operation
// 0 + 0 --> 00 result = 0
// 0 + 1 --> 01 result = 1
// 1 + 0 --> 01 result = 1
// 1 + 1 --> 10 result = 0 (ignored that "1", already taken care above)
$a ^= $b;
// now: shift carry bits to the next bit-locations to be added to $a in
// next iteration.
// PHP_INT_MAX here is used to ensure that the most-significant bit of the
// $b will be cleared after shifting. see link in the side note below.
$b = ($c >> 1) & PHP_INT_MAX;
}
return $a;
}
Side note: See this question about shifting negative values.
And as for test; start from zero and increment value by 8-bit reversed one (10000000):
$value = 0;
$add = 0x80; // 10000000 <-- "one" as bit reversed
for ($count = 20; $count--;) { // loop 20 times
printf("%08b\n", $value); // show value as 8-bit binary
$value = RevSum($value, $add); // do addition
}
... will output:
00000000
10000000
01000000
11000000
00100000
10100000
01100000
11100000
00010000
10010000
01010000
11010000
00110000
10110000
01110000
11110000
00001000
10001000
01001000
11001000
Let assume number 1110101 and our task is to find next one.
1) Find zero on highest position and mark position as index.
11101010 (4th position, so index = 4)
2) Set to zero all bits on position higher than index.
00001010
3) Change founded zero from step 1) to '1'
00011010
That's it. This is by far the fastest algorithm since most of cpu's has instructions to achieve this very efficiently. Here is a C++ implementation which increment 64bit number in reversed patern.
#include <intrin.h>
unsigned __int64 reversed_increment(unsigned __int64 number)
{
unsigned long index, result;
_BitScanReverse64(&index, ~number); // returns index of the highest '1' on bit-reverse number (trick to find the highest '0')
result = _bzhi_u64(number, index); // set to '0' all bits at number higher than index position
result |= (unsigned __int64) 1 << index; // changes to '1' bit on index position
return result;
}
Its not hit your requirements to have "no bits" operations, however i fear there is now way how to achieve something similar without them.

Resources