On learning and problem solving

At first I wanted to write a post about drawing lots of particles, but now I had a beer and I am to lazy and tired to finish it. You see I am quite afraid of being wrong on the Internet. It was a small pet project I’ve done some time ago and I am a bit unsure of some things so I have to double-check them. In any case, soon enough I’ll post that one too, just not today.

Instead I’ve decided to write about something else.

I’ve started to believe that in order to do something right you have to do it in a stupid way and work your way up from there. That way you can actually understand the underlying idea behind of certain algorithms, optimizations, etc. Often you might re-discover them yourself and see that some are not complicated at all, but instead quite obvious.
Other times I’ve discovered that the simple, stupid way of doing things might be good enough. Simply applying recipes from papers/tutorials, etc will get you nowhere and you might think that you understand something, but most often you don’t get the reason behind why a certain problem was solved in a certain way.

There is no real gain or fun in applying recipes. Actually blindly applying a solution might have the opposite effect compared to the one that you are trying to achieve.

Obviously, the most dangerous and evil type of recipes are design patterns. For the people who don’t know what patterns are I will briefly describe them and what they are all about.

First, we have the Captain Obvious patterns:
Often you see the most obvious solutions complicated a bit and classified as a pattern. For example the iterator pattern (btw, iterators were in STL before pattern books were written). Someone felt that this is a pattern and they just labeled it as such. You can’t say iterators are not useful.
You know what else is useful ?
The i in for(int i = 0; i < n; i++). That is quite useful, but I don’t give it a funky name and pretend it’s the best thing invented since sliced bread.

Second, we have the “we’re doing this for the future” patterns:
They lure you with solutions, most often to problems you didn’t know you had. You get “generic”-like systems that are future proof and extensible. In practice this means that there is 80% boilerplate code that sets stuff up, creates a “perfect” scene for things to happen and then 20% of the remaining code does the actual and most often trivial work. Some might argue that the boilerplate is there to make systems extensible. But they are not extensible because most often the future predicted has nothing to do with the reality of things.

As an example, at the following link we have a super-generic and future proof way to compute the distance between points – boost geometry

So my experience has thought me that the best way to gain a deep understanding of a problem (even a complicated one) is to write the simplest, dumbest solution for it and start from there. I end up either improving it, either throwing it out and choosing something else. But this second choice will be an informed one since I already know the disadvantages of the previous attempt at a solution. Rinse and repeat until we have something good enough.

This could be applied even when learning about some funky algorithm or trick that you read about in Game programming gems or something similar. See what problem it tries to solve, do it yourself, understand the problems of your method, compare it with the algorithm and this way you will most likely get a deeper and more valuable insights.


Leave a Reply