The other day I got a question from a colleague: *Do you know an algorithm for
this problem of … details…details?* The exact the problem description is
not important. It was a well defined problem which totally made sense. I felt
that there must be an algorithm for it, but I couldn’t help. I just simply
didn’t *know* any.

I didn’t have a formal training on algorithms and complexity. Yes, I can easily write an \(\mathcal{O}(n^2)\) sorting algorithm. Probably I can even make it \(\mathcal{O}(n \log n)\), but I wouldn’t enjoy it. Of course, I quickly learned that I shouldn’t write my own sorting algorithm. Countless hours of thinking went into inventing, refining all sorts of algorithms so I better reach for libraries written by smart people and use those instead.

Most programming languages provide basic algorithms such as finding the minimum or maximum element in a sequence, sorting and so on. Sometimes we can get away with these “built-in” algorithms, but often we need to provide a more complex solution. In real world problems data are noisy, things can fail and just nothing is as simple as in textbook examples.

We may try to combine the provided basic algorithms as building blocks to solve
our particular problem. Sounds reasonable, right? *Tackle complexity by
composition* the mantra says. But if you’re given `erase`

and `remove_if`

to
eliminate elements that fulfill a certain criterion from a C++ container, would
you come up with the Erase-remove idiom? I wouldn’t. For example, in the
talk STL Algorithms in Action from CppCon 2015 Michael VanLoon solves
interesting sorting problems using components from the `<algorithm>`

library.
None of those solutions are trivial.

Building algorithms is hard, even if you have the basic components available. It takes special expertise and a lot of time. I don’t have this expertise, but I still want to help my colleagues to solve their domain specific problem.

The point Nicolas Ormrod makes in his great talk Fantastic Algorithms and
Where To Find Them, is that algorithms are *tools*: you need to know they
exist and you need to be able to use them. It doesn’t matter if you built the
tool yourself (which is still very impressive), but how many different problems
you can solve with it. The more tools you have in your toolbox, the more
algorithms you know, the more problems you can solve.

One of piece of advice the book The Pragmatic Programmer gives (section
*Your Knowledge Portfolio* in Chapter 1) is that you should learn at least one
new programming language every year. I’d say you should also learn a new
algorithm every month. So next time when you’re asked if you know an algorithm
that solves a certain problem you can reach into your toolbox and answer:
*yeah, this algorithm can solve a problem which looks very similar to yours,
maybe it would be a good fit…*