|
||||||
Title: A puzzler Post by u_think_u_succeed on Jul 22nd, 2007, 1:53am Given a number, how can u determine using C, whether it is divisible by 3, without using *, /, % operators. You may assume that itoa() function is available. |
||||||
Title: Re: A puzzler Post by I_am_searching on Jul 22nd, 2007, 6:21am convert the number to the string using itoa(); add up all the digits checkDivisibility(int num){ char *str=itoa(num) while (1) { for (i =0 ; i < strlen(str);i++) sum= sum + (str[i] - "0"); if (sum > 10) str=itoa(sum); else break; } if(sum == 3 || sum == 6 || sum == 9) printf("Number divisible by 3"); else printf("Number not divisible by 3"); } |
||||||
Title: Re: A puzzler Post by I_am_searching on Jul 22nd, 2007, 6:23am Correction.... add sum=0; just at the beginning of while loop |
||||||
Title: Re: A puzzler Post by towr on Jul 22nd, 2007, 7:04am Doesn't seem very nice to use itoa How about something along the lines of Code:
[edit]Added the >>1 for (n & 2) which was mistakenly left out. (Pointed out in replies 30,32)[/edit] |
||||||
Title: Re: A puzzler Post by u_think_u_succeed on Jul 22nd, 2007, 8:03am Towr, Could you please explain the logic .. ? |
||||||
Title: Re: A puzzler Post by towr on Jul 22nd, 2007, 9:09am on 07/22/07 at 08:03:03, u_think_u_succeed wrote:
1 = 1 (mod 3) 2 = -1 (mod 3) 4 = 1 (mod 3) etc Adding the bits alternately positive and negative can therefore be used for the divisibility test. Just like when you test for 11 in decimal. (For testing divisibility by 3 in decimal you add all digits, because 10n = 1 (mod 3) ). And of course you can repeat this until you have a number n, 0 http://www.ocf.berkeley.edu/~wwu/YaBBImages/symbols/le.gif n < 3. So we take Nk = a * 22 + b * 21 + c * 20, with a http://www.ocf.berkeley.edu/~wwu/YaBBImages/symbols/ge.gif 0 and b,c http://www.ocf.berkeley.edu/~wwu/YaBBImages/symbols/in.gif {0,1} And turn it into Nk+1 = a - b + c |
||||||
Title: Re: A puzzler Post by towr on Jul 22nd, 2007, 9:58am An approach based on the bit counting puzzle. Code:
First take the absolute value of n. Then calculate the sum of digits in base 4: a base 4 number is divisible by 3 if the sum of its digits is divisible by 3. With a 32 bit integer we sum 16 digits, so we get at most a sum of 47 (*); which is contained in the last 6 bits of n. We can sum these as 3, base-4 digits again, and the result fits in 3 bits (**). And then as final steps we checks divisibility by 3: add bit 1 and 3 and subtract bit 2, if this yield 0 we have a number divisible by 3. (*) We could get 48 only if all bits were 1s, but that can only be for n=-1 and we take the absolute value before summing the base-4 digits. (**) If we could get a sum of 48 at (*), we might spill into the 4th bit, but luckily that's avoided. PS, those bitmasks should probably not be written in binary, because C might mistake them for octal instead; but for clarity's sake I think writing it as bitmasks makes sense. |
||||||
Title: Re: A puzzler Post by u_think_u_succeed on Jul 22nd, 2007, 11:30am Marvellous Towr !! :D ::) Hats off to you. Well, if we know the size of the number a priori, then simply adding bits 0, 2,4, 6,8, ... 31 and subtracting bits 1,3,5,7,...30; and testing if the result is zero will do the trick (i.e. if the result is zero, then the number is divisible by 3). |
||||||
Title: Re: A puzzler Post by towr on Jul 22nd, 2007, 11:48am on 07/22/07 at 11:30:08, u_think_u_succeed wrote:
|
||||||
Title: Re: A puzzler Post by u_think_u_succeed on Jul 22nd, 2007, 11:51am Any more examples of such type ? ::) |
||||||
Title: Re: A puzzler Post by towr on Jul 22nd, 2007, 11:54am In general in base b : a*bn = a (mod b-1) and a*bn = a (mod b+1) for even n and a*bn = - a (mod b+1) for odd n So for binary, you can easily do things for n = 3,5,7,9,15,17,31,33 etc. For the other numbers it will be more work (because you're dealing with longer sequences that repeatedly 1 or alternating 1 and -1.) [edit]switched b and n halfway through writing..[/edit] |
||||||
Title: Re: A puzzler Post by u_think_u_succeed on Jul 22nd, 2007, 8:36pm Well, how about this extension, given a number, you now actually need to divide that number by 3. The same constraints apply : No use of *, /, % operators. Again it may assumed that itoa() is available. |
||||||
Title: Re: A puzzler Post by towr on Jul 23rd, 2007, 12:39am You could do a binary search for the largest K such that N > (K << 1 + K ). I'm sure there's a more clever way, but I'll need to think a bit. |
||||||
Title: Re: A puzzler Post by Grimbal on Jul 23rd, 2007, 1:04am on 07/22/07 at 07:04:08, towr wrote:
Arhum... I must have been posting random text by mistake while cleaning my keyboard... :-[ This being said, the alternate bit count solution is nice. |
||||||
Title: Re: A puzzler Post by towr on Jul 23rd, 2007, 2:05am on 07/23/07 at 01:04:05, Grimbal wrote:
|
||||||
Title: Re: A puzzler Post by u_think_u_succeed on Jul 23rd, 2007, 2:21am Quote:
I doubt I understand the above, but binary search anyway might involve some use of / operator. Do you have any solution (even if it runs in linear time in number of bits) in mind ? |
||||||
Title: Re: A puzzler Post by towr on Jul 23rd, 2007, 2:29am on 07/22/07 at 20:36:09, u_think_u_succeed wrote:
I think this should work: [edit v2]Fixed the function to handle negative n. There is some choice whether you want -2 div 3 to be 0 or -1, I choose the latter.[/edit] Code:
Rationale: multiply by 1/3 = 0.01010101.. (binary) step 1 = 1.01 N step 2 = 1.010101 N step 3 = 1.01010101010101 N step 4 = 1.010101010101010101010101010101 N step 5 = 0.01010101010101010101010101010101 N [edit]Some frantic editing was needed because I had the wrong order (I had the final 2-right-shift at the top, which yielded wrong answer; this should now be fixed. And hopefully the rest of the reasoning is now correct.[/edit] [edit v2]Adding 1 at the start is more effective[/edit] It seems actually dividing by three might yield a more efficient divisibility test than the earlier approaches. [edit v2]Just test with k=div3(n) whether (k+ k<<1) == n [/edit] |
||||||
Title: Re: A puzzler Post by towr on Jul 23rd, 2007, 2:30am on 07/23/07 at 02:21:46, u_think_u_succeed wrote:
Quote:
|
||||||
Title: Re: A puzzler Post by I_am_searching on Jul 23rd, 2007, 2:35am How abt my soln....does it not confirms to what actually the problem states.... ne comments.... i dont understand these bit fiddlings at all.... :( ;D |
||||||
Title: Re: A puzzler Post by I_am_searching on Jul 23rd, 2007, 2:37am and now i have started hating these bit manipulation operations as I screwed up My google 3rd interview today jus beacuse of these bits... :( :( |
||||||
Title: Re: A puzzler Post by towr on Jul 23rd, 2007, 2:39am on 07/23/07 at 02:35:56, I_am_searching wrote:
|
||||||
Title: Re: A puzzler Post by I_am_searching on Jul 23rd, 2007, 2:41am yeah towr.... I approached the problem as it was stated ...... I need to start thinking out of the box!!!!!! :-X |
||||||
Title: Re: A puzzler Post by Shashikant on Jul 25th, 2007, 12:29am int ans=0; While(num<=3) { num = num-3; ans = ans+1; } if(num==0) printf("Number is divisible by 3 and Answer is %d",ans); else printf("Number not divisible by 3 and Answer is %d and remainder is %d",ans,num); |
||||||
Title: Re: A puzzler Post by towr on Jul 25th, 2007, 12:42am on 07/25/07 at 00:29:10, Shashikant wrote:
|
||||||
Title: Re: A puzzler Post by gowrikumar on Jul 25th, 2007, 10:19pm on 07/22/07 at 01:53:18, u_think_u_succeed wrote:
Here is what I can think of : The decimal equivalent of a binary representation of number abcdef is (where all a,b,c,d,e,f are either zero or 1): 2^0 * f + (2^1) * e + (2^2) * d + (2^3) *c + ..... (Note : ^ is used to denote power (and not xor:-) Now replace 2 by 3-1 in the above representation (3-1)^0 *f + ((3-1)^1)*e + ((3-2)^2)*d + .... Applying binomial theorm, we can notice that each of the every term of the expansion (3-1)^n will have a 3 except the last term, which would either be a 1 or -1 depending on the value of n. We can use this observation as follows: - Get every bit in the number - check if it is 1 - If so, add -1 or 1 depending on the position of the bit. If the resutant sum is dicisible by 3, then the original number is divisible by 3. The implementation of it is as follows (the code also includes the verification part): Code:
There is further optimization possible: It is possible to do away with the array. We can try simulating a finite state machine which keeps track of the modulo 3, with the sum. |
||||||
Title: Re: A puzzler Post by Sameer on Jul 26th, 2007, 9:05am on 07/23/07 at 02:37:28, I_am_searching wrote:
Working in bits can be trick especially if you are new to it... Here's how you can improve it!! Take some numbers and manually try to convert them to binary, octal and hex!!! (You can verify your answer using a calculator). Once you are able to do this pretty fast you will realize doing bit manipulations is easy. You will see that expressing a number in HEX is very convenient.. It allows you to quickly express numbers in binary and understand it as well as quickly apply the bit manipulations to it.. Soon you will be an expert!! :D Anybody else want to add to this? |
||||||
Title: Re: A puzzler Post by mad on Jul 31st, 2007, 3:34pm With the stream of bits input from one end... find if it is divisible by 3.. |
||||||
Title: Re: A puzzler Post by towr on Aug 1st, 2007, 12:50am on 07/31/07 at 15:34:48, mad wrote:
|
||||||
Title: Re: A puzzler Post by el_nino on Aug 2nd, 2007, 8:08pm if (n < 0) n = -n; n = n & 00110011001100110011001100110011 + (n >> 2) & 00110011001100110011001100110011; n = n & 00001111000011110000111100001111 + (n >> 4) & 00001111000011110000111100001111; n = n & 00000000111111110000000011111111 + (n >> 8) & 00000000111111110000000011111111; n = n & 00000000000000001111111111111111 + (n >> 16) & 00000000000000001111111111111111; n = n & 3 + (n >> 2) & 3 + (n >> 4) & 3; towr , can you please explain the above code to me. i am new to this bit fiddling |
||||||
Title: Re: A puzzler Post by towr on Aug 3rd, 2007, 12:43am on 08/02/07 at 20:08:20, el_nino wrote:
You skipped the last lines though; so what you have here is only part that adds the digits of the absolute value in base 4. What I'm doing essentially is at each step sum two adjacent partial sums (starting with the single digits). Because the result of summing two n-bit number won't be greater than 2n bits, you don't have to worry about the partial sums carrying over into each other; this allows doing sums parallel. So if e.g. we have base-4 number 10230212 (and we want 1+0+2+3+0+2+1+2) we first make the sum 0030202 + 1020001 = 1110203 (representing 1+11+2+3) then 0110003 + 10002 = 120011 (representing 12+11) then 11+12 = 23, which is the sum of the digits in base 4 (i.e. 11 in decimal). |
||||||
Title: Re: A puzzler Post by aileen529 on Oct 2nd, 2007, 6:30pm on 07/22/07 at 07:04:08, towr wrote:
should it be n = (n & 1) - (n & 2)>>1 + n >> 2; ? |
||||||
Title: Re: A puzzler Post by saurabh.ngarg on Oct 5th, 2007, 7:19pm To test the divisibility by 3 and if we are allowed to use itoa function, we can first convert the number to base 3 using itoa and check this least significant digit in the string. if it is zero...number is divisible by 3 else not. |
||||||
Title: Re: A puzzler Post by naveen on Oct 5th, 2007, 11:54pm on 07/22/07 at 07:04:08, towr wrote:
I think, the assignment in while loop should be n = (n & 1) - (n & 2)>>1 + n >> 2; As we are extracting the bits and alternatively adding & subtracting them so we have to right shift the second one to get the bit at one's place. Otherwise , it will not provide the desired results. |
||||||
Title: Re: A puzzler Post by towr on Oct 6th, 2007, 12:25pm on 10/02/07 at 18:30:55, aileen529 wrote:
on 10/05/07 at 23:54:31, naveen wrote:
|
||||||
Title: Re: A puzzler Post by johny_cage on Nov 25th, 2007, 7:47am on 07/22/07 at 07:04:08, towr wrote:
@towr, plz explain with an example, i tried the above code, it is not working... correct me if i m wrong.... |
||||||
Title: Re: A puzzler Post by towr on Nov 25th, 2007, 8:15am The reason it doesn't work is because I haven't fixed the error pointed out in the last few posts. The correct line should be n = (n & 1) - (n & 2)>>1 + n >> 2; So if we take 71 = 64+4+2+1 = 1000111 (in binary) 1000111 -> 1 - 1 + 10001 = 10001 -> 1 - 0 + 100 = 101 -> 1 - 0 + 1 = 10 = 2 (in decimal) 2 < 3 and 2 http://www.ocf.berkeley.edu/~wwu/YaBBImages/symbols/ne.gif0, so 3 does not divide 71 (in fact it has remainder 2) |
||||||
Title: Re: A puzzler Post by johny_cage on Nov 27th, 2007, 12:33pm on 07/22/07 at 09:58:24, towr wrote:
@towr Please elaborate it more, I am not able to get it. :'( |
||||||
Title: Re: A puzzler Post by towr on Nov 27th, 2007, 12:53pm on 11/27/07 at 12:33:12, johny_cage wrote:
You sum the digits of the number as represented in base 4 (in 4 steps) If N is divisible by 3, then so must this (for the same reason it works in decimal 10i = 1 (mod 3), and likewise 4i = 1 (mod 3) ) Then you have at most a 3-digit number (in base 4), so sum those 3 together again, the result spans at most 3 bits. And then test divisibility by 3; a binary number is divisible by 3, if alternately adding/subtracting the bits yields 0. e.g. 2 = 10 -> -1 + 0 = -1 3 = 11 -> -1 + 1 = 0 9 = 1001 -> -1 + 0 + -0 + 1 = 0 |
||||||
Title: Re: A puzzler Post by johny_cage on Nov 27th, 2007, 1:31pm @towr i appreciate your feedback. My problem : I am using your code, but it is not giving the output as expected. I think, I m not getting its usage, i used it as : Code:
Please correct my usage if it is wrong. |
||||||
Title: Re: A puzzler Post by johny_cage on Nov 27th, 2007, 1:43pm hey towr after observing the values quite several times, now i m getting it.... :) but i am thinking that the following line might be having problem... Quote:
Moreover, can we do one thing, just sum up all the even bits and odd bits separately in one go. Then subtract them, if it is 0, then number is divisible by 3 else not. This way, same method of counting bits can be used here, and algorithm is no longer slower. For odd bits case, i mean just AND the number by 0x33333333 first and then count the set bit as you told in this post earlier. For even case, right shift the number by 1, and follow the same above written algorithm. Then add them. Hope, what i m saying is clear to you? |
||||||
Title: Re: A puzzler Post by towr on Nov 27th, 2007, 1:56pm on 11/27/07 at 13:43:18, johny_cage wrote:
This problem is actually one of the rare occasions I actually tested my code, and it all worked fine for me then. [edit]Hmm, I can't seem to find my program, and I hardly ever throw something away, so maybe I'm being delusional again ;)[/edit] Quote:
So you need to reduce things further Quote:
|
||||||
Title: Re: A puzzler Post by towr on Nov 27th, 2007, 2:09pm Note, changing n==0 to n invalidates the warranty ;) [edit]Also, it seems those last two lines do need some extra parentheses; so you're right in your assertion something was amiss with them. Of course, conceptually, everything worked brilliantly, just as it should. ;D[/edit] |
||||||
Title: Re: A puzzler Post by johny_cage on Nov 27th, 2007, 2:16pm Code:
Now for input, 17, it is showing output as : Answer by towr is : Num : 2 Num : 0 True Please explain, where i am missing something... :'( |
||||||
Title: Re: A puzzler Post by towr on Nov 27th, 2007, 2:19pm on 11/27/07 at 14:16:04, johny_cage wrote:
But using n = (n & 3) + ((n >> 2) & 3) + ((n >> 4) & 3); n = (n & 1) - ((n >> 1) & 1) + ((n >> 2) & 1); seems to do the trick (might be overkill on the parentheses, but better safe than sorry, apparently) |
||||||
Title: Re: A puzzler Post by johny_cage on Nov 27th, 2007, 2:24pm Now, I am getting the answer. Hmmmm, so this was the problem who kill my 2 hrs, and also trouble you a lot with my replies. Thanks for your kind support. :) |
||||||
Title: Re: A puzzler Post by SMQ on Nov 28th, 2007, 6:40am Yeah, I trip over those occasionally too. Bitwise operators are very low precedence in C and C-like languages (C++, Java, Perl, etc.). In broad terms, from highest precedence to lowest: Member/Element access, e.g. [] . ->, and function calls Unary operators, e.g. ++ -- - !, and type casts Standard Arithmetic operators, e.g. * / % + - Shifts, e.g. << >> Comparison operators, e.g. == != <= Bitwise operators, e.g. & | ^ Boolean operators, e.g. && || The ternary operator ? : Assignments, e.g. = += >>= So minimally, you need: n = (n & 3) + (n >> 2 & 3) + (n >> 4 & 3); n = (n & 1) - (n >> 1 & 1) + (n >> 2 & 1). --SMQ |
||||||
Powered by YaBB 1 Gold - SP 1.4! Forum software copyright © 2000-2004 Yet another Bulletin Board |