Let's Learn it Together !

ِAn educational blog from FCIS'2011 students ..


There’s a “category” of questions that is commonly asked in large companies’ interviews that tests your thorough understanding of a certain programming language. I’ll send you an episode each time I remember one of them…

Represent x ? y : z as function int ternary(int x, int y, int z); using only ~, !, ^, &, +, |, << and >>. You’re not allowed to use -, * or if-else.

Solution 1:

int ternary(int x, int y, int z)

{

int ret[2] = {y, z};

return ret[!x];

}

The only comment here is that if x is 0, !x is 1… and if x is NOT 0, which means true in C++ as you probably know; !x is 0 – which is exactly what we want to index the array properly.

Solution 2:

int ternary(int x, int y, int z)

{

int t;

(!x && (t = z)) || (x && (t = y));

return t;

}

This one is actually important. Remember that the expression t = z (or t = y) evaluates to z (or y), and in the same time loads in t the correct value. That’s why we can depend on t in the end.

Thanks to F.M.A.R. who sent me this problem...

This is the pdf version of this article.

14 comments:

هى مين
F.M.A.R.
اللى كل شوية تبعت لحضرتك مسائل دى :D

:-D !وإيه اللي خلاك تفترض إنها بنت ؟

انا بصراحة مش فاهم حاجة

thanks dr omar
i think we should have some experience to be familiar of things like (!x && (t = z)) || (x && (t = y));
i dont know the use of && || without if and else and even what is the use of the above statement
so i ask you for some help :$

Thanx dr.Omar for the brilliant solutions :),
Also i think we can simplify the second solution to this,
(!x && (t = z)) || (t = y);

And we can write the first solution as follows,

int ret[2]={z,y};
return ret[x];

Thus, we saved the time of the ! operation, didn't we :D?

Of course not, Amr! The x can be anything, not necessarily 1! So, your solution easily throws an index-out-of-range exception...

Hmmmmmmmmm,
Got it now :), thanx dr.Omar .

Ok, i tried the following piece of code,

int ternary(int x,int y,int z)
{
int ret[2]={z,y};
return ret[bool(x)];
}

and it seems to be working, which one is faster now, the ! or the casting to type bool operation :D???

:-D ...ده أنت مصرّ بقى

.حاضر، هاشوفها وأقول لك

Thank you for your persistence! :-)

SA
The second solution cannot be rewritten as:
(!x && (t = z)) || (t = y);

This is because if x = 0, z = 0, y = non-zero, t will be assigned y. To see this, observe that:
!x evaluates to true
t = z evaluates to false
!x && (t = z) evaluates to false
So, || will not short-circuit and will evaluate the operand t = y.

Mohammed Fathy

Shokran ya DR 3ala el tas7ee7 da,
el wa7ed me7tag yrakez w howwa bykteb ay 7aga.

Regarding the issue of (which is faster), I had a discussion with more than one friend - and I am completely convinced of the general conclusion we reached: "The whole issue is fully dependant on the machine instructions that the compiler produces for each code fragment". So, may be a machine’s instruction set (assembly code) contains the NOT instruction but doesn’t contain an instruction for the cast. So, the NOT will be done in one machine cycle, but the cast in more than one. May be another machine has the opposite… and so on.

Thanx ya Dr.Omar, Rabena y5aleko leena w nefdal net3alem menko 3alatool :).

Post a Comment