How would I got about solving for the variable num, which would be my own input to the program, in the compare function?
main function (part)
int input;
answer = compare(input);
if(answer !=0xb88202) {
printf("Keep trying!");
exit(0);
}
puts("You got it");
compare function
uint compare(uint num) {
return (num ^ 0x735) >> 4 ^ 0x6f0;
}
I'm honestly not sure how to go about this. I figured somehow reversing the XOR with another XOR would help. I also tried left shifting 0xb88202 by the 4 ^ 0x6f0 but I just can't figure this out.
Just reverse the operations in the compare function.
input = (0xb88202 ^ 0x6f0) << 4 ^ 0x735
Treat it as an equation and solve. You have
answer == ((num ^ 0x735) >> 4) ^ 0x6f0
xor is its own inverse, so you get
answer ^ 0x6f0 == (num ^ 0x735) >> 4
(answer ^ 0x6f0) << 4 == (num ^ 0x735)
((answer ^ 0x6f0) << 4) ^ 0x735 == num
This isn't quite correct for the shift as a right shift loses bits (shifted off the bottom) that the left shift won't recover, but this just means that there are multiple values of num that will give you that answer and this finds one of them.
Related
As part of my coding class, an intro to C, I'm working on a coding project dealing with bit manipulation under restrictions. On this question in particular, I'm stuck because I don't know how to fix my error.
/*
* SigBitMask - return a mask that marks the position of the
* most significant 1 bit. If x == 0, return 0
* Example: SigBitMask(96) = 0x40
* Legal operations: ! ~ & ^ | + << >>
* Max operations: 16
* Rating: 4
*/
Besides the legal operations listed, I can't use any statements such as do, if, while, or else. I'm not allowed cast to other data types either., this includes using unsigned. Also I can't use any constant bigger than 0xFF, which is super important for this problem since I'm not allowed to use 0x80000000. Also, assume we are using a 32 bit machine.
A big thing here is that I can't use operations like - or * which would make this a lot easier.
Here is my code so far:
int SigBitMask(int x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x = x ^ (x >> 1);
return x & ~(x >> 1);
}
The error the checking software is giving me says:
"ERROR: Test SigBitMask(-2147483648[0x80000000]) failed...
...Gives 0[0x0]. Should be -2147483648[0x80000000]
I'm not quiet sure how to go about fixing my problem. I'd prefer more than just the answer. Can someone actually explain the process too. The whole point of this project is to learn to code in C. Thanks :)
Edit: I know there is a similar problem on Stack Overflow already, but their restrictions were different than mine, plus I'm looking for help fixing my code, and understanding why.
Edit2: Clarified what max and legal ops meant
Get rid of your last line because it doesn't do anything. So your function becomes:
int SigBitMask(int x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x ^ (x >> 1);
}
This works great for non-negative inputs, but for negative inputs, x will be -1 when the last line runs, so the last line will give a result of zero. But that's bad, because we want to return -2147483648 (i.e. 0x80000000) for all negative inputs.
What if we could patch the return expression, by using | to combine it with another expression that is 0x80000000 when x is -1, and 0 when is x is non-negative? (We don't care about its values for other negative values of x.) Can you think of such an expression? I can think of one using only 3 operators, but it involves a little bit of undefined behavior.
I'm working on CS50's pset 5, speller. I need a hash function for a hash table that will efficiently store all of the words on the dictionary (~140,000). I found this one online, but I don't understand how it works. I don't know what << or ^ mean. Here is the hash function, thank you! (I would really appreciate it if you could help me :))
int hash_it(char* needs_hashing)
{
unsigned int hash = 0;
for (int i=0, n=strlen(needs_hashing); i<n; i++)
hash = (hash << 2) ^ needs_hashing[i];
return hash % HASHTABLE_SIZE;
}
Those two are Bit-wise operators. These are easy to learn and must to learn for a programmer.
<< - is a binary left shift operator.
Suppose variable "hash" binary is "0011".
hash << 2 becomes "1100".
And ^ is XOR operator. (If set in only one operand ...not in both)
Suppose in your code
hash << 2 gives "1100"
needs_hashing[1] gives "1111"
then
(hash << 2) ^ needs_hashing[i] gives "0011"
For a quick understanding bitwise operators, quickly walk here
https://www.tutorialspoint.com/cprogramming/c_bitwise_operators.htm
In the original topic, is demonstrated very inefficient hash function. Two lowest bits of hash after calculation equals to two lowest bits of last char within input line needs_hashing. As result, for example, if all strings contains even ascii-code of last char, then all your hashes also would be even, if HASHTABLE_SIZE is even (2^n, or so).
More efficient hash, based on cyclic shift:
uint32_t hash_it(const char *p) {
uint32_t h = 0xDeadBeef;
while(char c = *p++)
h = ((h << 5) | (h >> (32 - 5))) + c;
h ^= h >> 16;
return h % HASHTABLE_SIZE;
}
This is part of a puzzle that I can't figure out. The function takes in three inputs. The first is an int, the second is the lower bound and the third is the upper bound. I need to test to see if that first number is within the lower and upper bound inclusive.
If it is in range then return 1, else return 0.
The catch is that I can only use
! ~ & ^ | + << >>
operations and only a combination of 20 of them.. Also, only int variables may be used, and no if statements, loops or function calls.
Range(int x, int lower, int upper){
//... some code here
return retVal;
}
Obviously I understand the logic here. If((x >= lower) && (x <= upper)) return 1;
The only problem is that I can't use if statements, <, >, ==, or &&.
You can make the comparison predicate x < y (returning -1 if true, 0 if false) like this: (see Hacker's Delight, Chapter 2, sub-chapter Comparison Predicates)
((x - y) ^ ((x ^ y) & ((x - y) ^ x))) >> 31;
You didn't list subtraction, but you can emulate x - y with ~(~x + y)
Using two of these predicates, make 1 & ~((x < lower) | (upper < x))
This obviously assumes 2's complement negatives and 32 bit integers with wrapping on overflow. So this is not portable, but that's the norm with this kind of trick.
As requested, that makes the total thing:
int in_range(int x, int lower, int upper)
{
int p = ((x - lower) ^ ((x ^ lower) & ((x - lower) ^ x))) >> 31;
int q = ((upper - x) ^ ((upper ^ x) & ((upper - x) ^ upper))) >> 31;
return 1 & ~(p | q);
}
It still has the subtractions, they're trivial to replace if you really want.
It's possible to make it a tiny tiny bit shorter by using the >= and <= predicates (which can also be found in Hacker's Delight).
Here's my website saying it's correct.
And here's a way that uses less operations, keeping in mind we can't use subtraction:
int p = (x | ~upper) & ((x ^ upper) | (~upper + x));
int q = (lower | ~x) & ((lower ^ x) | (~x + lower));
return 1 & ((p & q) >> 31);
It uses the <= predicate from HD, which looks like (x | ~y) & ((x ^ y) | ~(y - x)) in its pure form.
And here's my website saying it's correct.
Here is a humble solution
int foo(int num, int upp, int low){
return (~((~(upp + ~num + 1)) ^ (~(num + ~low + 1))) >> 31) & 1;
}
do this. i'll tell the logic that can be used.
a=~x+1 //gives -x
b=lower+a //lower-x
c=~upper+1 //gives -upper
d=x+c //x-upper
b=b&0x80000000; //get the msb which is 1 if -ve number
d=d&0x80000000;
return ((b&d)|(!(x^lower))|(!(x^upper))); //& results in +ve only if both b & d are +ve
I'm liking these puzzles you have! For this you will want to have something like,
Ok to be abstract on this one, you will want to have 2 variables.
The first variable (lets call it blarg) you need to set the upper bound and add the flipped x.
Now you will want to add one to blarg and flip it.
Your second variable (lets call it hold) will add the x to the flipped lower bound; After that add 1 to hold and flip it too.
set blarg = to the blarg plus hold;
shift blarg over 31 to the the right.
and AND it with 1.
Should be what you are looking for.
This is part of a puzzle that I can't figure out. The function takes in three inputs. The first is an int, the second is the lower bound and the third is the upper bound. I need to test to see if that first number is within the lower and upper bound inclusive.
If it is in range then return 1, else return 0.
The catch is that I can only use
! ~ & ^ | + << >>
operations and only a combination of 20 of them.. Also, only int variables may be used, and no if statements, loops or function calls.
Range(int x, int lower, int upper){
//... some code here
return retVal;
}
Obviously I understand the logic here. If((x >= lower) && (x <= upper)) return 1;
The only problem is that I can't use if statements, <, >, ==, or &&.
You can make the comparison predicate x < y (returning -1 if true, 0 if false) like this: (see Hacker's Delight, Chapter 2, sub-chapter Comparison Predicates)
((x - y) ^ ((x ^ y) & ((x - y) ^ x))) >> 31;
You didn't list subtraction, but you can emulate x - y with ~(~x + y)
Using two of these predicates, make 1 & ~((x < lower) | (upper < x))
This obviously assumes 2's complement negatives and 32 bit integers with wrapping on overflow. So this is not portable, but that's the norm with this kind of trick.
As requested, that makes the total thing:
int in_range(int x, int lower, int upper)
{
int p = ((x - lower) ^ ((x ^ lower) & ((x - lower) ^ x))) >> 31;
int q = ((upper - x) ^ ((upper ^ x) & ((upper - x) ^ upper))) >> 31;
return 1 & ~(p | q);
}
It still has the subtractions, they're trivial to replace if you really want.
It's possible to make it a tiny tiny bit shorter by using the >= and <= predicates (which can also be found in Hacker's Delight).
Here's my website saying it's correct.
And here's a way that uses less operations, keeping in mind we can't use subtraction:
int p = (x | ~upper) & ((x ^ upper) | (~upper + x));
int q = (lower | ~x) & ((lower ^ x) | (~x + lower));
return 1 & ((p & q) >> 31);
It uses the <= predicate from HD, which looks like (x | ~y) & ((x ^ y) | ~(y - x)) in its pure form.
And here's my website saying it's correct.
Here is a humble solution
int foo(int num, int upp, int low){
return (~((~(upp + ~num + 1)) ^ (~(num + ~low + 1))) >> 31) & 1;
}
do this. i'll tell the logic that can be used.
a=~x+1 //gives -x
b=lower+a //lower-x
c=~upper+1 //gives -upper
d=x+c //x-upper
b=b&0x80000000; //get the msb which is 1 if -ve number
d=d&0x80000000;
return ((b&d)|(!(x^lower))|(!(x^upper))); //& results in +ve only if both b & d are +ve
I'm liking these puzzles you have! For this you will want to have something like,
Ok to be abstract on this one, you will want to have 2 variables.
The first variable (lets call it blarg) you need to set the upper bound and add the flipped x.
Now you will want to add one to blarg and flip it.
Your second variable (lets call it hold) will add the x to the flipped lower bound; After that add 1 to hold and flip it too.
set blarg = to the blarg plus hold;
shift blarg over 31 to the the right.
and AND it with 1.
Should be what you are looking for.
I need to determine if a signed 32 bit number is a power of two. So far I know the first thing to do is check if its negative since negative numbers cannot be powers of 2.
Then I need to see if the next numbers are valid etc... SO I was able to write it like this:
// Return 1 if x is a power of 2, and return 0 otherwise.
int func(int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
But for my assignment I can only use 20 of these operators:
! ~ & ^ | + << >>
and NO equality statements or loops or casting or language constructs.
So I am trying to convert the equality parts and I know that !(a^b) is the same as a == b but I cant seem to figure it out completely. Any ideas on how to covert that to the allowed operators?
Tim's comment ashamed me. Let me try to help you to find the answer by yourself.
What does it mean that x is power of 2 in terms of bit manipulation? It means that there is only one bit set to 1. How can we do such a trick, that will turn that bit to 0 and some other possibly to 1? So that & will give 0? In single expression? If you find out - you win.
Try these ideas:
~!!x+1 gives a mask: 0 if x==0 and -1 if x!=0.
(x&(~x+1))^x gives 0 if x has at most 1 bit set and nonzero otherwise, except when ~x is INT_MIN, in which case the result is undefined... You could perhaps split it into multiple parts with bitshifts to avoid this but then I think you'll exceed the operation limit.
You also want to check the sign bit, since negative values are not powers of two...
BTW, it sounds like your instructor is unaware that signed overflow is UB in C. He should be writing these problems for unsigned integers. Even if you want to treat the value semantically as if it were signed, you need unsigned arithmetic to do meaningful bitwise operations like this.
First, in your solution, it should be
return ((x > 0) && ((x & (~x + 1)) == x));
since negative numbers cannot be the power of 2.
According to your requirement, we need to convert ">", "&&", "==" into permitted operators.
First think of ">", an integer>0 when its sign bit is 1 and it is not 0; so we consider
~(x >> 31) & (x & ~0)
this expression above will return a non zero number if x is non-positive. Notice that ~0 = -1, which is 0x11111111. We use x & ~0 to check if this integer is all 0 at each digit.
Secondly we consider "&&". AND is pretty straight forward -- we only need to get 0x01 & 0x01 to return 1. So here we need to add (!!) in front of our first answer to change it to 0x01 if it returns a nonzero number.
Finally, we consider "==". To test equity of A and B we only need to do
!(A ^ B)
So finally we have
return (!!(~(x >> 31) & (x & ~0))) & (!((x&(~x+1)) ^ x))
It seems that it's a homework problem. Please don't simply copy and paste. My answer is kind of awkward, it might be improved.
Think about this... any power of 2 minus 1 is a string of 0s followed by a string of 1s. You can implement minus one by x + ~0. Think about where the string of 1s starts with relation to the single 1 that would be in a power of 2.
int ispower2(int x)
{
int ispositive= ! ( (x>>31) ^ 0) & !!(x^0);
int temp= !((x & ~x+1) ^ x);
return temp & ispositive;
}
It is interesting and efficient to use bitwise operators in C to solve some problems. In this question, we need to deal with two checks:
the sign check. If negative, return 0; otherwise return 1;
! (x >> 31 & ox1) & !(!x)
/* This op. extracts the sign bit in x. However, the >> in this case will be arithmetic. That means there will be all 1 before the last bit(LSB). For negative int, it is oxFFFFFFFF(-); otherwise, oxFFFFFFFE(+). The AND ox1 op. corrects the >> to ox1(-) or ox0(+). The Logical ! turns ox1(-) and ox0 (+) into 0 or 1,respectively. The !(!x) makes sure 0 is not power(2)*/
the isPower(2) check. If yes, return 1; otherwise 0.
!( x & (~x + ox1) ^ x )
/* This op. does the isPower(2) check. The x & (~x + ox1) returns x, if and only if x is power(2). For example: x = ox2 and ~x + ox1 = oxFFFFFFFE. x & (~x + ox1) = ox2; if x = ox5 and ~x + ox1 = oxFFFFFFFB. x & (~x + ox1) = ox1. Therefore, ox2 ^ ox2 = 0; but ox5 ^ ox1 = ox4. The ! op turn 0 and others into 1 and 0, respectively.*/
The last AND op. between 1 and 2 checks will generate the result of isPower(2) function.