Programmers: please learn when to not use while loops

Hey, the difference between silly and genius is often very small. I’m thinking in terms of big-O execution time not the “avoid a goto” syndrome. If I were simply out to eliminate the goto then I’d use returns. I was doing a little off-the-cuff and out-of-the-box musing about execution time optimization. Looping constructs are always the first place I look when trying to figure out ways to speed something up. A triple-nested loop raises a red flag right away. Upon review it may be the best way to do things, but because it is something you want to get as inexpensive as possible, I’d entertain other thoughts. Note that the jumpgate players had analyzed the generation of the items they are looking for and discovered they were not fully random(very few things are) and are exploiting the pseudo-randomness of this particular game feature to make it easier to find an optimal pattern. It may be possible that the distribution of the items you are seeking is also less than perfectly random and you can incorporate that assumption into your search algorithm.

Two other possible solutions that came to mind. If you’re looking for something in some space, which the X,Y,Z seems to indicate, and the item is hidden in some random portion of the space, then a brute-force “examine every single point” may not be the best option, especially from a performance standpoint. There are statistically proven search patterns which will find the item within some tolerance. They will undoubtedly be more difficult to implement in code, but the execution time would be much shorter because you’re searching a subset instead of the whole set. You could say with XX% certainty that you’d find the object, but take far less time to actually do the search. Players of the game JumpGate have developed extensive search pattern algorithms which minimize the amount of time they spend searching any given space and maximize their chance of finding the object. A similar search pattern, or at least the process used to derive these, may work for your application.

If you want to stick with brute-force and check every single possible co-ordinance in the space, then it may be possible to find a way to increment a single number and then mod it by different values so that you end up searching the whole space but without the nested loops. Then you only need a couple namespaces and you are doing less checks(remember that a for does a check every time the conditional is evaluated). Also remember that with a for loop you can count by more than one at a time. maybe you want for (i=1; i<something; i + 2) and then mod it by 3, 5, and 7. On your first pass you’d check 1,1,1 next pass you’d check 0,3,3 next pass 2,0,5 next pass some other co-ordinate, etc. This would mean your control structure only has to ever perform one test, is i < something, and if you pick the right initial point, incrementor, and mod values, you should be able to hit the vast majority, if not all, the possible points. Tough math though, and probably not worth it for a project which will only have a couple years worth of lifespan, but the algorithm may have execution time superiority over the brute force method you outlined. It would be up to you to determine if that would be worth investigating/implementing.

Enjoy,
Steven

See, that’s what I get for previewing. The addendum I had intended to make to the second paragraph ended up at the end of the first. Sorry about that. The second paragraph should look like this.

Enjoy,
Steven

Menstruating Christ!

The point of the triply nested loop was not to triply nest a for loop to search over a cube. It was to have a triply nested loop, because if there wasn’t one, then there’s no reason not to do this:



x = 0

do
{
  if (found(x))
  {
     foundFunc();
     break;

     x++;

    if (x == 100)
    {
       NotFoundFunc();
       break;
    }
}
while (1);


which requires no unneeded compares or function calls (assuming that while(1) gets properly optimized), and also requires no goto. However, if there’s a doubly nested loop, I believe that a goto is required…

The first thing you learn when programming is that specs always change. Coding with spec change in mind makes for good programming practise. At the very least, your building up a reusable code library. Don’t get me wrong, I completely agree that error checking can become excessive, I just think your % 2 example was the worst possible one you could have chose. To determine whether you should add a sanity check or not, multiply the likelyhood of making that error by the average time spent fixing it and see if it is longer than the time it takes to code in a sanity check. Now, I would say % 2 errors would be about medium on the likelyhood scale, nothing special. The negative number comment a while back definately sent of alarm bells since negatives popping up where you expect positives is a big, BIG source of error(unexpected return codes and integer overflows mainly) and definately should be checked. I was previously unaware that negative numbers would produce negative mods, but if that is the case, then it’s really inexcusable to not have some sort of sanity checking on mods. But % 2 errors can be horrendously, grieviously time consuming to debug because it’s a bug that can stay silent for many hundreds of lines only to bite you in the ass in a completely unrelated place. Almost any other example would have worked much better in your case.

And second of all, you need to give your students a break, it takes many years of experience to become comfortable with writing code comfortably enough that you know what sort of mistakes your especially prone to. In the meantime, it’s far, far better to over-compensate than undercompensate. After all, natural human laziness will adjust them to the ideal level. But if you start off writing under-commented code, then it takes a miracle from above for you to start providing more documentation. I would say they should be encouraged, at least they are thinking about writing code at a production type level rather than your sterile little toy assignments.

I’m not sure exactly what part of our miscommunication is causing the frustration which leads to exclamations like “Menstruating Christ!” but I apologize for anything I have done to cause it. It was not my intention. Ironically one of my own pet peeves is someone taking a situation which was intended to be a hypothetical and overanalyzing it to address pretty much everything but the main point. In my defense I did not know you were only offering it as a hypothetical. I thought it was an actual snippet regarding a specification you had actually implemented. It looks very much like code to search a specific volume for some hidden object. Given that you have mentioned your background as a game programmer in the past it was an easy step to assume you were relating an algorithm you used in a game.

Enjoy,
Steven

When did anyone here ever check the return code from printf()?

Not me. No point is there?

A guy here wrote a listener program with a little polling loop waiting for a control file to be written. Writing to the console:

file not found
file not found
file not found
file. . .

Unfortunately someone wanted to run it in the background and redirected the output to a file. Oops.

Eventually printf() must have failed since the user filespace was full of hundeds of Megs of “file not founds”. But the program carried on regardless.
In real life programming checking for absurd errors can be a lifesaver.

Exceptions are your friend.

I wasn’t really frustrated in an angry sense, which is why I chose a wacky epithet from The Onion.

Anyhow, I think the quite minor miscommunication has now been cleared up, so I will say no more.

(And in any case, I could never be mad at someone whose love of Magic: The Gathering is reflected in his username! :slight_smile: )

Ah, I didn’t recognize the source, that made it seem more like an angry epithet than a lighthearted one.

Well, I still think gotos are bad. Maybe the lesser or some evils, but still bad. :wink:

And in the name of one of his children.

Impending hijack warning. Anyone who is not interested in the game Magic: the Gathering, please stop reading now.

We hosted a bunch of players Saturday night and my inner Johnny, never far from the surface, overrode my inner Spike once a big multi-player had gotten down to the final three players. One had just cast Obliterate which put us all pretty much back at starting points. I drew a Stormbind and was starting to clean house of every creature being played and occasionally nibbling a head until it was Allayed. Not daunted I dropped a Sliver Queen, intending to make short work of the other players, one of whom was at nine and the other at seven. I was at seven as well. The one at seven played Control Magic and stole the Sliver Queen(I made a couple tokens in response). The one at nine played a Two-Headed Dragon. Now I was in a pickle. I had a Savage Twister in hand, and enough mana to pop it for seven, wiping the board and putting us back on an even footing, but not really hurting either actual player. My two Sliver tokens were clearly not going to cut the mustard. I also had a Balance which could reset us as well, but not unless I could find a way to get rid of the tokens. All in all I was in a pretty happy place, relatively speaking, with plenty of solutions to my problems and a strong deck with which to draw threats from. Then it happened. I drew a Kaervek’s Purge. Now the Johnny in me just screamed “IT’S POETIC JUSTICE TIME!” I tried to resist the urge, the Savage Twister would be a better play, or the Balance if I could tempt my fellow players into killing the tokens for me. But Johnny would not be denied and I laughed as I tapped seven mana and cast the purge on my traitorous Sliver Queen. She blew up and did seven damage to the player who stole her, thus killing him. I had the mana left to Balance as well, but I had forgotten to attack with my tokens so I couldn’t sweep away the Two-Headed Dragon and he clobbered me next turn.

Oh well, winning isn’t as much fun as losing with style.

Enjoy,
Steven

From back in the OP:

Actually, the first case is cleaner and more readable as


for (value = initial_value; value != 0; value = get_next_value())
{
    //do stuff
}

Damn kids these days, and their K&R brace style. :stuck_out_tongue:

I don’t know what the “K&R” stands for, but I’m with you, tracer. Put the open/close braces on the same vertical drop and indent all the insides.

Had a student once come to me for compiler help – was obviously problems with his blocks. They were all over the place, not lined up in any easy-to-read way – too many levels of nesting. Ran his source through a quick program I had to count the braces. He had something like 92 opening braces and 84 closing ones.

Monstre: “There’s your problem. But sorry, I’m not going to find them all for you!”

Ya know what tracer? I agree with you. I have no idea why I wrote it like that.

The only place where I deviate is that an else clause for me is always:
} else {

I just don’t think that splitting it into three lines makes it more readable, especially if both blocks are indented relative to the else line.

-lv

K&R stands for Kernigan and Ritchie. They wrote C Programming Language and were the developers of the C language. They promote the

if(somthing){
dosomething();
};

style of coding. I detest and forbid it in my coding standards.

Thanks, Khadaji – I do know who Kernighan and Ritchie are, just never seen them specifically referred to with K&R, and wasn’t particularly aware that they were in love with that bracketing style.

I don’t like it, either. When open brackets are missing, it’s harder to find the errors, IMHO. I’m definitely a:



if (blah blah blah)
{
    // do stuff
}


kind of guy. :slight_smile:

BALR.

And menstruating Christ? Sin verguenza.

(For the record, them braces should be vertical. K&R were on crack or something when they came up with that bracketing style.)

Eh. All you really have to do is make sure you use an editor that enforces an indentation style (such as the One True Editor[sup]TM[/sup], emacs[sup]1[/sup]). You can tell something’s gone wrong when your code no longer indents properly.


[sup]1. I figured this “rant,” such as it is, was getting way too friendly, so why not start a classic editor war?[/sup]

Sure, always an option. As I teach a fairly early C++ programming course, I prefer not to teach my students immediate reliance on tools, but rather to develop a consistent style and learn how to recognize things themselves (this goes for debugging, too – i.e. hand testing vs. relying solely on debugger programs).

Sorry Monstre, I didn’t mean to come off as condescending.

Write every loop inside a seperate function.

Kerningham didn’t develop the C programming language. That was Ritchie and Thompson.

You may be right. I took my information from the publishers of C Prog Language Ansi C 2ND Edition who say:

But publishers are sometimes wrong too…