I found this snippet on 'codefights' submitted by a programmer. My solution to the problem was 30 lines, whereas this is just a beauty.
But I am not able to understand the logic.
Can anyone explain this.
int mirrorBits(int a) {
int r = 0;
for (; a; a >>= 1)
r = r << 1 | a & 1;
return r;
}
input a = 8; output : 1
First of all, there is a very good StackOverflow answer here:
Most Efficient Algorithm for Bit Reversal ( from MSB->LSB to LSB->MSB) in C
The algorithm makes use of
>> ... binary shift right (100b >> 1 == 10b)
<< ... binary shift left (100b << 1 == 1000b
| .... binary or (100b | 10b == 110b)
& .... binary and (111b & 100b == 100b)
The for loop shifts a to the right until all bits have fallen out of a.
Imagine you start with a = 101101 then a >>= 1 does the following:
At the end of loop 1: a == 10110
At the end of loop 2: a == 01011
At the end of loop 3: a == 00101
At the end of loop 4: a == 00010
At the end of loop 5: a == 00001
At the end of loop 6: a == 00000 (condition fails -> loop ends)
The body of the loop shifts b one bit right, uses & to mask the last bit of a and adds it as last digit to b. The or can be used to add the last digit because << inserts 0 for all "new" bits.
Imagine you start with a = 101101
loop 1: a = 101101, r = 0 => 01
loop 2: a = 010110, r = 01 => 010
loop 3: a = 001011, r = 010 => 0101
loop 4: a = 000101, r = 0101 => 01011
loop 5: a = 000010, r = 01011 => 010110
loop 6: a = 000001, r = 010110 => 0101101
In detail the inner loop #3 does the following:
(a is 001011 and r is 010)
r << 1 changes r from 010 to 0100. The last digit is the inserted 0.
a & 1 masks the current last bit from a (the 1 in 001011)
now we have (0100 | 1) which has the result 0101.
Warning: This algorithm is not really mirroring the bits, because you do not get the original value if you apply the algorithm to the result.
If you need a mirrored 32-bit unsigned integer you have to loop 32 times independently of the value of a:
unsigned int r = 0;
unsigned int a = 12345;
for(int i = 0; i < 32; ++i)
{
r = (r << 1) | (a & 1);
a >>= 1;
}
If you apply this algorithm twice, you should get the original value.
Related
In a binary representation of a number is there a simpler way than this
long half(long patten, bool exclusive) {
if (patten == 0) {
return 1;
}
long newPatten = 0;
for (int p = 0; p < MAX_STEPS; p++) {
long check = 1 << p;
if ((check & patten) > 0) {
int end = (p + MAX_STEPS) - 1;
for (int to = p+1; to <= end; to++) {
long checkTo = 1 << (to % MAX_STEPS);
if ( (checkTo & patten) > 0 || to == end ) {
int distance = to - p;
long fullShift = (int)round( ((float)p) + ((float)distance)/2 );
long shift = fullShift % MAX_STEPS;
long toAdd = 1 << shift;
newPatten = newPatten | toAdd;
break;
}
}
}
}
return exclusive ? patten ^ newPatten : patten | newPatten;
}
To add a bit in the middle of any two other bits with wrapping around and rounding to one side when there is an even number of positions between?
E.g.
010001 to
110101
Or
1001 to
1101
Update: These bits aren't coming from anywhere else, such as another number, just want a new True bit to be in the middle of any other two True bits, so if there was a 101, then the middle would be the 0 and the result would be 111. Or if we started with 10001, then the middle would be the center 0 and the result would be 10101.
When i say wrapping i also mean adding bits as if the bit array was a circle so if we had 00100010 representing the positions with letters:
00100010
hgfedcba
So we have True bits at b and f we would put a middle bit between b and f going left to right at d but also going right to left, wrapping around and putting it at h resulting in:
10101010
hgfedcba
I understand this isn't a usual problem.
Are there known tricks to do things like this without loops?
The number is huge (cannot fit in the bounds of unsigned long long int in C++). How do we check?
There is a solution given here but it doesn't make much sense.
The solution here tries to repeatedly divide the large number (represented as a string) by 2 but I'm not sure I understand how the result is reached step by step.
Can someone please explain this or propose a better solution?
We cannot use any external libraries.
This is the sample code:
int isPowerOf2(char* str)
{
int len_str = strlen(str);
// sum stores the intermediate dividend while
// dividing.
int num = 0;
// if the input is "1" then return 0
// because 2^k = 1 where k >= 1 and here k = 0
if (len_str == 1 && str[len_str - 1] == '1')
return 0;
// Divide the number until it gets reduced to 1
// if we are successfully able to reduce the number
// to 1 it means input string is power of two if in
// between an odd number appears at the end it means
// string is not divisible by two hence not a power
// of 2.
while (len_str != 1 || str[len_str - 1] != '1') {
// if the last digit is odd then string is not
// divisible by 2 hence not a power of two
// return 0.
if ((str[len_str - 1] - '0') % 2 == 1)
return 0;
// divide the whole string by 2. i is used to
// track index in current number. j is used to
// track index for next iteration.
for (int i = 0, j = 0; i < len_str; i++) {
num = num * 10 + str[i] - '0';
// if num < 2 then we have to take another digit
// to the right of A[i] to make it bigger than
// A[i]. E. g. 214 / 2 --> 107
if (num < 2) {
// if it's not the first index. E.g 214
// then we have to include 0.
if (i != 0)
str[j++] = '0';
// for eg. "124" we will not write 064
// so if it is the first index just ignore
continue;
}
str[j++] = (int)(num / 2) + '0';
num = (num) - (num / 2) * 2;
}
str[j] = '\0';
// After every division by 2 the
// length of string is changed.
len_str = j;
}
// if the string reaches to 1 then the str is
// a power of 2.
return 1;
}
I'm trying to understand the process in the while loop. I know there are comments but they arent really helping me glean through the logic.
Let's start by figuring out how to halve a "string-number". We'll start with 128 as an example. You can halve each digit in turn (starting from the left), keeping in mind that an odd number affects the digit on the right(a). So, for the 1 in 128, you halve that to get zero but, because it was odd, five should be kept in storage to be added to the digit on its right (once halved):
128
v
028
Then halve the 2 as follows (adding back in that stored 5):
028
v
018
v
068
Because that wasn't odd, we don't store a 5 for the next digit so we halve the 8 as follows:
068
v
064
You can also make things easier then by stripping off any leading zeros. From that, you can see that it correctly halves 128 to get 64.
To see if a number is a power of two, you simply keep halving it until you reach exactly 1. But, if at any point you end up with an odd number (something ending with a digit from {1, 3, 5, 7, 9}, provided it's not the single-digit 1), it is not a power of two.
By way of example, the following Python 3 code illustrates the concept:
import re, sys
# Halve a numeric string. The addition of five is done by
# Choosing the digit from a specific set (lower or upper
# digits).
def half(s):
halfS = '' # Construct half value.
charSet = '01234' # Initially lower.
for digit in s: # Digits left to right.
if digit in '13579': # Select upper for next if odd.
nextCharSet = '56789'
else:
nextCharSet = '01234' # Otherwise lower set.
halfS += charSet[int(digit) // 2] # Append half value.
charSet = nextCharSet # And prep for next digit.
while halfS[0] == '0': # Remove leading zeros.
halfS = halfS[1:]
return halfS
# Checks for validity.
if len(sys.argv) != 2:
print('Needs a single argument')
sys.exit(1)
num = sys.argv[1]
if not re.match('[1-9][0-9]*', num):
print('Argument must be all digits')
sys.exit(1)
print(num)
while num != '1':
if num[-1:] in '13579':
print('Reached odd number, therefore cannot be power of two')
sys.exit(0)
num = half(num)
print(num)
print('Reached 1, was therefore power of two')
Running that with various (numeric) arguments will show you the process, such as with:
pax$ python ispower2.py 65534
65534
32767
Reached odd number, therefore cannot be power of two
pax$ python ispower2.py 65536
65536
32768
16384
8192
4096
2048
1024
512
256
128
64
32
16
8
4
2
1
Reached 1, was therefore power of two
(a) Take, for example, the number 34. Half of the 3 is 1.5 so the 1 can be used to affect that specific digit position but the "half" left over can simply be used by bumping up the digit on the right by five after halving it. So the 4 halves to a 2 then has five added to make 7. And half of 34 is indeed 17.
This solution does work only for numbers which are not too large i.e. fits in the range of unsigned long long int.
Simpler C++ solution using bitmanipulation for small numbers :-
int power(string s) {
// convert number to unsigned long long int
// datatype can be changed to long int, int as per the requirement
// we can also use inbuilt function like stol() or stoll() for this
unsigned long long int len = s.length();
unsigned long long int num = s[0]-'0';
for(unsigned long long int i = 1; i<len; i++)
num = (num*10)+(s[i]-'0');
if(num == 1)
return 0;
//The powers of 2 have only one set bit in their Binary representation
//If we subtract 1 from a power of 2 what we get is 1s till the last unset bit and if we apply Bitwise AND operator we should get only zeros
if((num & (num-1)) == 0)
return 1;
return 0;
}
A bit better solution that I could code in Java, which doesn't use any fancy object like BigInteger. This approach is same as simple way of performing division. Only look out for remainder after each division. Also trim out the leading zeroes from the quotient which becomes new dividend for next iteration.
class DivisionResult{
String quotient;
int remainder;
public DivisionResult(String q, int rem){
this.quotient = q;
this.remainder = rem;
}
}
public int power(String A) {
if (A.equals("0") || A.equals("1")) return 0;
while (!A.equals("1")){
DivisionResult dr = divideByTwo(A);
if (dr.remainder == 1) return 0;
A = dr.quotient;
}
return 1;
}
public DivisionResult divideByTwo(String num){
StringBuilder sb = new StringBuilder();
int carry = 0;
for (int i = 0;i < num.length(); i++){
int divisibleNum = carry*10 + (num.charAt(i) - '0');
carry = divisibleNum%2;
sb.append(divisibleNum/2);
}
return new DivisionResult(sb.toString().replaceAll("^0+(?!$)", ""), carry);
}
This is the code which generates possible permutation using bit masking. I am having problem in understanding how is it executing after this condition when i = 2 , bit = 4 , mask = 7.
when bit is 4 and mask is 7 so condition (bit & mask) == true So it will continue .How i = 2 again ? and how mask becomes 1 when Mask will change when it will execute recurse(....)
#include <iostream>
#include <string>
using namespace std;
void recurse(string s, int mask = 0,string out = "")
{
int n = s.length();
if (out.length() == n) cout << ' ' << out<<endl;
for (int i = 0; i < n; i++) {
cout<<"I:"<<i<<"=>";
unsigned bit = 1 << i;
cout<<bit<< " -> " <<mask<<endl;
cout<<"cond:"<<(mask & bit)<<endl;
if (mask & bit) continue;
cout<<out+s[i]<<endl;
recurse(s, mask | bit, out + s[i]);
}
}
int main()
{
string test = "red";
recurse(test);
cout << endl;
return 0;
}
Output:
I:0=>1 -> 0
cond:0
r
I:0=>1 -> 1
cond:1
I:1=>2 -> 1
cond:0
re
I:0=>1 -> 3
cond:1
I:1=>2 -> 3
cond:2
I:2=>4 -> 3
cond:0
red
red
I:0=>1 -> 7
cond:1
I:1=>2 -> 7
cond:2
I:2=>4 -> 7 <===== here when bit is 4 and mask is 7 so condition (bit & mask) == true
cond:4 So it will continue .How i = 2 again ? and how mask becomes 1 when Mask will change when it will execute recurse(....)
I:2=>4 -> 1
cond:0
rd
I:0=>1 -> 5
Since you are using a recursive algorithm, you need to stop recursing when you reached the termination condition (in your case it is out.length() == n). If this condition is triggered, you print found permutation, but what happens immediately after this? You continue to execute the function. In particular, you will iterate through the for loop which will print some output (meaningless at this point, because you reached the bottom of recursion). In fact, you got confused by the output messages printed after the recursion termination condition triggered. Add the return statement to your check for recursion termination:
if (out.length() == n) {
cout << "OUT: " << out << endl;
return;
}
This way you will avoid redundant recursive calls and won't see irrelevant output messages that can be confusing.
As for your question about why mask doesn't change - note that for values of mask = 7 and bit = 4 you get maks | bit = 7| 4 = 7 = mask. So in some cases, bitwise OR-ing mask and bit will not affect the mask.
After the continue i = 3, and since n = 3 the loop stops.
So it goes up one recursion step and continues from the loop:
I:0=>1 -> 1
cond:1
I:1=>2 -> 1
cond:0
re
You can try printing a statement saying something like "finished loop" to see this.
I hope this answers your question.
I am making a program for nth Fibonacci number. I made the following program using recursion and memoization.
The main problem is that the value of n can go up to 10000 which means that the Fibonacci number of 10000 would be more than 2000 digit long.
With a little bit of googling, I found that i could use arrays and store every digit of the solution in an element of the array but I am still not able to figure out how to implement this approach with my program.
#include<iostream>
using namespace std;
long long int memo[101000];
long long int n;
long long int fib(long long int n)
{
if(n==1 || n==2)
return 1;
if(memo[n]!=0)
return memo[n];
return memo[n] = fib(n-1) + fib(n-2);
}
int main()
{
cin>>n;
long long int ans = fib(n);
cout<<ans;
}
How do I implement that approach or if there is another method that can be used to achieve such large values?
One thing that I think should be pointed out is there's other ways to implement fib that are much easier for something like C++ to compute
consider the following pseudo code
function fib (n) {
let a = 0, b = 1, _;
while (n > 0) {
_ = a;
a = b;
b = b + _;
n = n - 1;
}
return a;
}
This doesn't require memoisation and you don't have to be concerned about blowing up your stack with too many recursive calls. Recursion is a really powerful looping construct but it's one of those fubu things that's best left to langs like Lisp, Scheme, Kotlin, Lua (and a few others) that support it so elegantly.
That's not to say tail call elimination is impossible in C++, but unless you're doing something to optimise/compile for it explicitly, I'm doubtful that whatever compiler you're using would support it by default.
As for computing the exceptionally large numbers, you'll have to either get creative doing adding The Hard Way or rely upon an arbitrary precision arithmetic library like GMP. I'm sure there's other libs for this too.
Adding The Hard Way™
Remember how you used to add big numbers when you were a little tater tot, fresh off the aluminum foil?
5-year-old math
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
Well you gotta add each column, right to left. And when a column overflows into the double digits, remember to carry that 1 over to the next column.
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
The 10,000th fibonacci number is thousands of digits long, so there's no way that's going to fit in any integer C++ provides out of the box. So without relying upon a library, you could use a string or an array of single-digit numbers. To output the final number, you'll have to convert it to a string tho.
(woflram alpha: fibonacci 10000)
Doing it this way, you'll perform a couple million single-digit additions; it might take a while, but it should be a breeze for any modern computer to handle. Time to get to work !
Here's an example in of a Bignum module in JavaScript
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We can verify that the Wolfram Alpha answer above is correct
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
bigfib (10000)
// "336447 ... 366875"
Expand the program below to run it in your browser
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s) .reverse ()
, toString: (b) =>
b .reverse () .join ("")
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = (n = 0) =>
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n > 0) {
_ = a
a = b
b = add (b, _)
n = n - 1
}
return toString (a)
}
console.log (bigfib (10000))
Try not to use recursion for a simple problem like fibonacci. And if you'll only use it once, don't use an array to store all results. An array of 2 elements containing the 2 previous fibonacci numbers will be enough. In each step, you then only have to sum up those 2 numbers. How can you save 2 consecutive fibonacci numbers? Well, you know that when you have 2 consecutive integers one is even and one is odd. So you can use that property to know where to get/place a fibonacci number: for fib(i), if i is even (i%2 is 0) place it in the first element of the array (index 0), else (i%2 is then 1) place it in the second element(index 1). Why can you just place it there? Well when you're calculating fib(i), the value that is on the place fib(i) should go is fib(i-2) (because (i-2)%2 is the same as i%2). But you won't need fib(i-2) any more: fib(i+1) only needs fib(i-1)(that's still in the array) and fib(i)(that just got inserted in the array).
So you could replace the recursion calls with a for loop like this:
int fibonacci(int n){
if( n <= 0){
return 0;
}
int previous[] = {0, 1}; // start with fib(0) and fib(1)
for(int i = 2; i <= n; ++i){
// modulo can be implemented with bit operations(much faster): i % 2 = i & 1
previous[i&1] += previous[(i-1)&1]; //shorter way to say: previous[i&1] = previous[i&1] + previous[(i-1)&1]
}
//Result is in previous[n&1]
return previous[n&1];
}
Recursion is actually discommanded while programming because of the time(function calls) and ressources(stack) it consumes. So each time you use recursion, try to replace it with a loop and a stack with simple pop/push operations if needed to save the "current position" (in c++ one can use a vector). In the case of the fibonacci, the stack isn't even needed but if you are iterating over a tree datastructure for example you'll need a stack (depends on the implementation though). As I was looking for my solution, I saw #naomik provided a solution with the while loop. That one is fine too, but I prefer the array with the modulo operation (a bit shorter).
Now concerning the problem of the size long long int has, it can be solved by using external libraries that implement operations for big numbers (like the GMP library or Boost.multiprecision). But you could also create your own version of a BigInteger-like class from Java and implement the basic operations like the one I have. I've only implemented the addition in my example (try to implement the others they are quite similar).
The main idea is simple, a BigInt represents a big decimal number by cutting its little endian representation into pieces (I'll explain why little endian at the end). The length of those pieces depends on the base you choose. If you want to work with decimal representations, it will only work if your base is a power of 10: if you choose 10 as base each piece will represent one digit, if you choose 100 (= 10^2) as base each piece will represent two consecutive digits starting from the end(see little endian), if you choose 1000 as base (10^3) each piece will represent three consecutive digits, ... and so on. Let's say that you have base 100, 12765 will then be [65, 27, 1], 1789 will be [89, 17], 505 will be [5, 5] (= [05,5]), ... with base 1000: 12765 would be [765, 12], 1789 would be [789, 1], 505 would be [505]. It's not the most efficient, but it is the most intuitive (I think ...)
The addition is then a bit like the addition on paper we learned at school:
begin with the lowest piece of the BigInt
add it with the corresponding piece of the other one
the lowest piece of that sum(= the sum modulus the base) becomes the corresponding piece of the final result
the "bigger" pieces of that sum will be added ("carried") to the sum of the following pieces
go to step 2 with next piece
if no piece left, add the carry and the remaining bigger pieces of the other BigInt (if it has pieces left)
For example:
9542 + 1097855 = [42, 95] + [55, 78, 09, 1]
lowest piece = 42 and 55 --> 42 + 55 = 97 = [97]
---> lowest piece of result = 97 (no carry, carry = 0)
2nd piece = 95 and 78 --> (95+78) + 0 = 173 = [73, 1]
---> 2nd piece of final result = 73
---> remaining: [1] = 1 = carry (will be added to sum of following pieces)
no piece left in first `BigInt`!
--> add carry ( [1] ) and remaining pieces from second `BigInt`( [9, 1] ) to final result
--> first additional piece: 9 + 1 = 10 = [10] (no carry)
--> second additional piece: 1 + 0 = 1 = [1] (no carry)
==> 9542 + 1 097 855 = [42, 95] + [55, 78, 09, 1] = [97, 73, 10, 1] = 1 107 397
Here is a demo where I used the class above to calculate the fibonacci of 10000 (result is too big to copy here)
Good luck!
PS: Why little endian? For the ease of the implementation: it allows to use push_back when adding digits and iteration while implementing the operations will start from the first piece instead of the last piece in the array.
The following Pseudo and JavaScript code is a extract from the implementation of a algorithm , i want to convert it to C++ .
Pseudo Code :
for b from 0 to 2|R| do
for i from 0 to |R| do
if BIT-AT(b, i) = 1 then // b’s bit at index i
JavaScript Code :
for (var b = 0; b < Math.pow(2, orders[r].length); b++) // use b's bits for directions
{
for (var i = 0; i < orders[r].length; i++)
{
if (((b >> i) & 1) == 1) { // is b's bit at index i on?
I don't understand what is happening in the last line of this code , What Should be the C++ code for the above given JavaScript code . So far what i have written is :
for (int b = 0; b < pow(2, orders.at(r).size()); b++)
{
for (int i = 0; i < orders.at(r).size(); i++)
{
if (((b >> i) & 1) == 1)***//This line is not doing what it is supposed to do according to pseudo code***
The last line is giving me segmentation fault .
--
Edit:I apologize the problem was somewhere else , This code works fine .
(((b >> i) & 1) == 1)
| |
| |
| bitwise AND between the result of the shift and number 1.
|
shift b by i bits to the right
After that the result is compared with the number 1.
So if, for example, b is 8, and i is 2, it will do the following:
shift 8 (which is 00001000) by 2 bits to the right. The result will be 00000100.
apply the bitwise AND: 00000100 BITWISE_AND 00000001, the result will be 0.
Compare it with 1. Since 0 =/= 1, you will not enter that last if.
As for the logic behind this, the code ((b >> i) & 1) == 1) returns true if the bit number i of the b variable is 1, and false otherwise.
And I believe that c++ code will be the same, with the exception that we don't have Math class in c++, and you'll have to replace vars with the corresponding types.
>> is the right shift operator, i.e. take the left operand and move its bit n positions to the right (defined by the right operand).
So essentially, 1 << 5 would move 1 to 100000.
In your example (b >> i) & 1 == 1 will check whether the i-th bit is set (1) due to the logical and (&).
As for your code, you can use it (almost) directly in C or C++. Math.pow() would become pow() inside math.h, but (in this case) you could simply use the left shift operator:
for (int b = 0; b < (1 << orders[r].length); ++b) // added the brackets to make it easier to read
for (int i = 0; i < orders[r].length; ++i)
if (((b >> i) & 1) == 1) {
// ...
}
1 << orders[r].length will essentially be the same as pow(2, orders[r].length), but without any function call.