Rewriting a loop without a loop body

Discussion in 'Mac Programming' started by cybrscot, Mar 6, 2011.

Thread Status:
Not open for further replies.
  1. cybrscot macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #1
    Problem *15. It has a "*" because it's supposedly a "tricky" problem. That being said, how can I approach this? What's so tricky about it?

    Rewrite the following loop so that it's body is empty.

    for (n = 0; m > 0; n++)
    m /= 2;
     
  2. itickings, Mar 6, 2011
    Last edited: Mar 6, 2011

    itickings macrumors 6502a

    itickings

    Joined:
    Apr 14, 2007
    #2
    I wouldn't really call it "tricky", but I like the problem type. You are supposed to demonstrate that you understand the concepts and parts of the for loop.

    Can't really say anything more than that without more or less solving it for you, which would be a bad thing. This is exactly the type of problem you need to solve by yourself. If you can't do it, for your own sake go back and repeat the related "non-tricky" problems and text. Someone solving it for you will only set you back.
     
  3. flashy-cat macrumors regular

    flashy-cat

    Joined:
    Apr 8, 2007
    Location:
    UK
    #3
    The code snippet given is completely pointless. What is the initial value for m? Whilst this is not necessary to answer the question, it does seem a bit stupid for an example which presumably is for beginners to c or programming.
     
  4. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #4
    Why should we do your homework again ? :rolleyes:

    Code:
    for(; m > 0; m >>= 1);
    Now please tell your teacher to grade me. Complete ANSI compliant code :

    Code:
    $ cat test.c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char ** argv)
    {
    	int m = 20;
    #ifdef DEBUG_OUT
    	printf("Start value of m : %d\n", m);	
    	
    	for(; m > 0; m >>= 1)
    		printf("Value of m now : %d\n", m);
    #endif
    #ifndef DEBUG_OUT
    	for(; m > 0; m >>= 1);	
    #endif
    	return EXIT_SUCCESS;
    }
    
    Compile with or without the debug output and proof of execution :

    Code:
    $ gcc -DDEBUG_OUT -pedantic -o test.debug test.c
    $ gcc -pedantic -o test test.c
    $ ./test.debug 
    Start value of m : 20
    Value of m now : 20
    Value of m now : 10
    Value of m now : 5
    Value of m now : 2
    Value of m now : 1
    $ ./test       
    $ echo $?
    0
    
    I suggest reading on Binary operators, the one we used here was the binary right shift.

    BONUS point : Do the same now for Floating point values so that when m = 5 and /2, it equals 2.5 or some approximation instead of 2.
     
  5. ulbador, Mar 6, 2011
    Last edited: Mar 6, 2011

    ulbador macrumors 68000

    ulbador

    Joined:
    Feb 11, 2010
    #5
    Gotta love how high-horsed people get on the Internet. From the OP's prior posts, they are just trying to learn on their own.

    And unless the OP fat fingered the initial example, I think your solution misses the point, though successfully and fancily doing the division by 2. This would allow you to count the number of times the division happens.

    Code:
    for(n = 0; (m /= 2) > 0; n++)
            printf("Value of m,n now : %d %d\n", m,n);
    
     
  6. KnightWRX, Mar 6, 2011
    Last edited: Mar 6, 2011

    KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #6
    No, my example does precisely what was asked in the OP. My solution missed the point if the OP fat fingered the example, not unless. That's me being "High horsed" or pedantic if you will. ;) EDIT : Maybe I came off strong, I guess the guys in the news section are getting on my nerves and I was battling a stupid warning in Xcode for the last 30 minutes, which was putting me on edge... Thank god that warning is gone now (stupid forgetting the @interface part of my declaration).

    I've been hanging on programming forums for the last 10 years, I've had my share of answering homework for others. People "just learning on their own" starting at a date right around the start of a semester and then disappearing right at the date that's quite conveniently the end of a semester. Notice I did answer his question, provided the entire code example for him to peruse through, even gave him glimpses on how to compile it himself and then gave him the ultimate reference : The Bitwise operators. Not so bad for someone just being "high horsed".

    And BTW, I doubt the OP fat fingered the example since there's no point in n in a loop without a body. The point was removing the body which was the m /= 2; part. Your solution is as good as mine. Actually, an even better one considering n is just pointless in a bodyless loop (at least for these 1 line examples) :

    Code:
    while((m >>= 1) > 0);
    If you're going to use n later in the program to know how many divisions occured, then sure, keep the counting there. (And btw, for a division by 2 on ints, the bit shift operator is much more efficient than a division, though compilers probably just optimize that away).
     
  7. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #7
    Seems like a simple question -

    which is equivalant to -

    Code:
        for ( n = 0; m > 0; )
        {
            m /= 2;
        
            n++;
        }
    
    which is itself equivalant to -

    Code:
        for ( n = 0; m > 0; m /= 2, n++)
            ;
    
     
  8. ulbador macrumors 68000

    ulbador

    Joined:
    Feb 11, 2010
    #8
    So... you just proved my point?
     
  9. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #9
    Actually, there's a difference between yours and Ulbador's solution :

    Code:
    $ gcc -pedantic -o test test.c
    $ ./test
    We divided 5 times
    We divided 4 times
    
    Both implementations give different results for n even though both have the same value of m :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char ** argv)
    {
            int m;
            int n;
    
            for(m = 20, n = 0; m > 0; m >>= 1, n++);
            printf("We divided %d times\n", n);
    
            for(m = 20, n = 0; (m >>= 1) > 0; n++);
            printf("We divided %d times\n", n);
    
            return EXIT_SUCCESS;
    }
    
    Being right depends on what result we want n to have. Since this is unspecified in the problem, we can't know the right answer. Is the fact we are counting n to know how many divisions it took for m to be == 0 or how many it took to give us the lowest possible value of m while still > 0 ? Depending on what was sought of n, we may have all missed the point (including you Ulbador...).

    Hence why I think the n value is just pointless in this exercise, which is just trying to show how to compact syntax. Next we should do if/else one-liners with the ? operator.
     
  10. itickings, Mar 6, 2011
    Last edited: Mar 6, 2011

    itickings macrumors 6502a

    itickings

    Joined:
    Apr 14, 2007
    #10
    Well, of course the snippet is completely pointless, what do you expect? Even more pointless than that however is asking for the initial value of m when it doesn't matter at all. ;)

    Anyways, while the snipped might be a tad pointless since it doesn't solve the Ultimate Question of Life, the Universe, and Everything, it is not stupid at all. The question obviously was at the end of the section teaching loops, and was marked as "tricky", not "monkey see, monkey do". If a beginner has worked through the chapter and understood it, the question should make perfect sense.

    I'd wager that being right is having understood how a for loop works and demonstrating it by incorporating the division in it... But I'm curious, since n is in the original loop and obviously gets a value there, why do you claim it is unspecified? In my opinion, it either isn't important at all or it should be the same as in the code given.
     
  11. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #11
    Exactly, we agree on that point.

    It's unspecified in the sense we don't know what n will be used for. It was shown between Ulbador's and lloydean's solutions that n can have different values depending on where in the for loop you do the actual division (ie, before we check the exit condition or after we do), even if it is the same in the code given.

    Given that n can have different values depending on the solution and the fact we don't know what n will even be used for, on my part, I think the n is simply there because a newbie to C doesn't realize a for loop can be written as for(;;) for all the compiler cares and the book/instructor doesn't want to go into explaining it at that point. Ultimately, if we want to absolutely reproduce the same value of n that the original snippet did, lloydean is the one with the most correct answer.
     
  12. subsonix, Mar 6, 2011
    Last edited: Mar 6, 2011

    subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #12
    Well, the solution is to create an equivalent solution without a loop body.
    The value of n is not what is being asked, but given your value of m the answer would be 5.
     
  13. itickings macrumors 6502a

    itickings

    Joined:
    Apr 14, 2007
    #13
    That's one way to interpret it. I'm just claiming that either it isn't important at all, or it should have the exact same value as in the supplied code.

    Ignoring the fact that it is a question intended for beginners and it is being way overanalyzed, rewriting the code and giving another value of n is worse than removing it completely in my opinion. Much harder to find bugs introduced after refactoring if you do something like that... Off-by-ones... Grr!

    Don't you just love those automatic smileys? ;)

    While I don't know what book it is, I think it is quite possible that it has hinted that such constructions are possible. In fact I believe that this specific problem was intended to demonstrate just that very fact.
     
  14. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #14
    I doubt Ulbador will appreciate you calling his answer the worst one in the thread but oh well. :D

    And yes, I do absolutely love automatic smileys... *sigh*.
     
  15. itickings macrumors 6502a

    itickings

    Joined:
    Apr 14, 2007
    #15
    Well, that code was by far the worst. If I was grading homework I'd only give partial credit for that answer even disregarding the n part, because it is really bad form to put the update code where it was put.

    But aside from the implementation I completely agree with ulbador.
     
  16. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #16
    Did you people even read the post? All that was given is -

     
  17. SidBala, Mar 6, 2011
    Last edited: Mar 6, 2011

    SidBala macrumors 6502a

    Joined:
    Jun 27, 2010
    #17
    Obviously the point of the snippet is to determine n. Why else you would keep dividing by two repeatedly?

    If n really is irrelevant, here is an even more epic way to do what you are doing above:

    Code:
    m = 0;
    
    And look! it's even faster than the fancy bit shifting! And this one also works with floats! :D
     
  18. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #18
    The purpose of any such code outside of a textbook example, yes. Here, n cannot be determined since m is unknown. But for any m, n should be the same for the given example and a correct answer. :)
     
  19. SidBala, Mar 6, 2011
    Last edited: Mar 6, 2011

    SidBala macrumors 6502a

    Joined:
    Jun 27, 2010
    #19
    Exactly!

    But since m will always be 0 for all (positive) values of m, the only relevant part of the snippet is n. And that is why I am saying that determining n is the whole point of the snippet, since determining m is trivial (m=0).

    If m is negative the solution is even more trivial (m stays the same). The combined solution, if n is irrelevant, will be:

    Code:
    if(m > 0)
    m = 0;
    Obviously, this is not what the textbook wants.



    But we know what exactly the book wants n to be. In fact, they've give us the whole snippet showing what n needs to be. The problem is fully qualified. The book wants a solution that is equivalent to the snippet.
     
  20. subsonix macrumors 68040

    Joined:
    Feb 2, 2008
    #20
    No, the textbook wants a solution that is equivalent to the example given.

    That is, the answer should produce the same n for any given m. This means that m can only be updated after the conditional check. I believe we are on the same page here. :)
     
  21. SidBala macrumors 6502a

    Joined:
    Jun 27, 2010
    #21
    Yes we are on the same page. I was just disputing KnightWRX's solutions.
     
  22. KnightWRX macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #22
    Then as I stated earlier :

    No need to try to explain to me something I already pointed out myself.

    My solution is the same as lloydean's, I just removed the n part as we weren't actually using n for anything in the example. It gave insight to the OP that you are not obligated to plug in code into every part of a for statement (you can leave the condition, the initialisation or the post iteration code empty and C is fine with that), but of course, then the loop becomes useless outside of textbook "syntax compaction" exercises.
     
  23. chrono1081 macrumors 604

    chrono1081

    Joined:
    Jan 26, 2008
    Location:
    Isla Nublar
    #23
    Wow was I over thinking things. I wrote a solution using recursion and totally forgot bitwise operators. (I never use them).
     
  24. ulbador macrumors 68000

    ulbador

    Joined:
    Feb 11, 2010
  25. cybrscot, Mar 7, 2011
    Last edited: Mar 7, 2011

    cybrscot thread starter macrumors 6502

    cybrscot

    Joined:
    Dec 7, 2010
    Location:
    Somewhere in Southeast Asia
    #25
    Hey thanks for your input, and your solution. However, if you can't take my sincerity at face value and are helping "reluctantly", then don't bother. I don't need you to assume that I'm in "school" and having you do my homework for me. Remember, assume (ass u me) means make an ass out of you and me. I'm a real grown-up! I'm not in school. If you looked at my profile you would see that I'm currently working in S.E. Asia. I'm from Orlando, Fl (Altamonte Springs to be exact) Trust me, there are no schools here that I can attend and no teachers to learn from. If I had a teacher, there would be no need for me to ask so many of the questions I have asked on this forum. I decided to learn programming in December. I would like to ultimately learn objective c, however as it's a subset of C, I'm learning C first. That's it! I hope you can believe that, I'm not trying to fool you or anybody else. Sorry your experience has made you so jaded.

    But again, thanks for your help.

    EDIT:
    No fat finger errors either, I double checked, I typed exactly what the book wrote. That's the problem it gave me!
    Thanks all!

    Code:
    $ cat test.c
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char ** argv)
    {
    	int m = 20;
    #ifdef DEBUG_OUT
    	printf("Start value of m : %d\n", m);	
    	
    	for(; m > 0; m >>= 1)
    		printf("Value of m now : %d\n", m);
    #endif
    #ifndef DEBUG_OUT
    	for(; m > 0; m >>= 1);	
    #endif
    	return EXIT_SUCCESS;
    }
    Also, I have no idea what most of your code even means. I have no clue about half the stuff you wrote. If you've been "doing my homework" for me, then you've been following my threads/posts. If you've been doing that then you would know what I have learned and where I'm at so far. Based on your code, you don't. You use several headers that I don't know, the char** and argv, and m>>=1, and debug. I don't know any of that yet, so your code doesn't help me as much as you intended to.



    Code:
    for ( n = 0; m > 0; m /= 2, n++)
            ;
    Thank you Lloyddean, I think this is exactly what I was looking for. I love it when somebody understands the question and doesn't overcomplicate it. What good is it for that "other" guy to give me such a complex piece of code that I won't understand and that is clearly way over the top. Then he goes on to say that he gave me the ultimate reference with the "bitwise" operators ( I don't even know what the heck they are), etc, etc. Examples like that don't help much. When I get those kinds of answers, it really looks like people are just trying to show off. Let's just keep it simple.
     
Thread Status:
Not open for further replies.

Share This Page