- Ensuring all of our UI updates are on the UI thread via use of InvokeRequired along with BeginInvoke or Invoke.
- Querying a database and making sure we correctly handle people named "Robert'); DROP TABLE Students; --"
- Making sure our classes have responsibilities and colloborate nicely with others
- Avoiding locks: either dead or alive
- Making sure we don't go peeking around the contents of whatever is at address zero. Besides, doing that is always segmentation's fault, not ours.
- Thinking about Cheshire Cats and pimpl-es
- Making sure our binary searches aren't broken
The list goes on and on.
But again I ask, when was the last time you were challenged by an algorithm?
I remember when I was 13 and writing a program for my aunt to help her schedule appointments for people. I had to make sure that people weren't scheduled on holidays like Christmas. I was writing the program in BASIC and it required me to learn things like Julian dates. Days like Christmas and the 4th of July were easy because they always fell on the same day each year. The first one to really give me problems was Thanksgiving. Every stinkin' year it was on a different date!
The solution baffled me at the time. I even made use of my access to this new thing called the "Internet" and asked puzzle gurus there for help. I believe later that day I went to Old Country Buffet with my family and kept thinking about it. After loading up on food, we were walking back to our car and it hit me: "start with the first Thursday in December and subtract 7 days!!" I already had code that told me what day of the week a Julian date fell on, so this was easy. After realizing this wouldn't work for Thanksgiving 1995 which was two months away, I think I corrected it to find the first Thursday in November and then calculate the right number of days afterwards.
I'm sure you're laughing at my early struggles. It's probably "intuitively obvious to [you,] the most casual observer" what the right algorithm is, but for my 13 year old self, it was hard.In college, I especially remember being challenged by algorithm problems like figuring out what words to suggest for a mispelled word. The algorithms were non-obvious and took time to figure out. However, in the end, I usually ended up growing in my understanding of computer science as a result of solving them and in the process added a few more tools to my algorithmic toolkit.
After graduating and entering "the real world," I rarely had to wrestle with an algorithm and instead focused on more tactical issues like the bullet points above. This always nagged at me; I felt as if I was somehow "rotting" in my computer science abilities. My thinking was that if I kept getting bogged down in the tactical, day-to-day stuff, I'd never be able to "hit the high notes" as a developer. It's been this fear of skills rot that has pushed me to look into Lisp, Haskell, F#, Erlang, and other languages to avoid The Blub Paradox. It's what drives me to attempt to attack code bloat, read modern papers and watch videos of people way smarter than myself. It's what makes me think of books like Code Complete, Code Craft, and Framework Design Guidelines each time I write code.
And lately, it's what drove me to the legacy of a dead mathematician. I found ProjectEuler.net last week. It is a website dedicated to problems that can be solved efficiently with a good algorithm that runs for less than a minute. It's in memory of the master mathematician, Leonhard Euler, who loved to "tinker" with mathematics and algorithms. I'm sure he'd probably work at Google if he were alive today.
What I love about ProjectEuler is that while some of the problems are very challenging, they are at least possible for me to solve. I've seen way too many contests that just are no fun because they take too long to solve or are just too hard.
Some took me only a few seconds to figure out, some have taken me an hour, and some I still haven't been able to solve. The real fun part is that once you solve the problem, you are granted access to a forum where people discuss their solutions. It's there where I've been most humbled. I might have taken 40 lines of code to figure out something someone did in a few minutes using a one line program in J, a language that I had never even heard of before. Still others will do it in Haskell or Python in a couple lines of code. Some brave guy consistently writes his solution in x86 assembler.
My approach has been to use C# 3.0's new features whenever possible. I was thrilled to be able to solve problem #19 in 1 line using LINQ concepts. I also really had fun with #56, writing an algorithm to decode a secret message. Although the site looks heavy on math, it's more about thinking algorithmically and no problems require fancy math beyond what you would have learned by high school.
I'm not saying ProjectEuler.net is the only way to improve as a developer. I'm sure some folks have very busy schedules with kids and other activities that make it almost impossible to study anything outside of work. However, I've found tackling a ProjectEuler problem can easily be more fun than watching an average weeknight TV show or just surfing the web in general, but that's just me.
What do you do to sharpen your algorithm saw? Are you registered on ProjectEuler? If so, what's your username? (Here's my profile) I'd love to learn from you if you post your solutions on the forums. It could be fun to have a friendly competition.