# Algorithms

## Types of Algorithms

## Analysis and Design

An Algorithm is simply a structured approach to solving a problem.

The solution to every hard problem lies in recursively decomposing it to a set of easier problems, and solving those in a certain order, utilizing existing technology when possible and inventing new technology as needed. The key to making progress is prioritizing the sub-problems and faithfully solving them in priority order.

### The hard thing about solving difficult problems is ...

The two major obstacles to solving any problem are **lack of awareness** and
**bias**.

Lack of awareness is pretty straightforward to understand. It's when a solution exists but a person just isn't aware of it. In this case the lack of awareness becomes the primary problem which is solvable through research and study over time.

Bias is trickier. It's when a persons OPINION about how a problem SHOULD be solved blocks them from seeing the ACTUAL solution. Every human being is vulnerable to this. And it's very real, with over 180 known types of cognitive bias.

Falling victim to bias isn't necessarily a reflection on a person. It's often a reflection on constraints imposed by context or circumstance. There may be constraints on time or resources that limit the breadth of a persons field of view in terms of what IS working and what ISN'T working as well as potential approaches to getting more things to work properly.

### How to Approach a Problem

TODO: Review and edit this. There's more to write here.

Fortunately, Data Structures give us a library of tools and patterns
to use when trying to understand a problem and a solution to it. Each Data Structure provides a
template for how to relate to a problem and a known set of strengths and weaknesses (based on both
structure and complexity). From this menu
of templates we can pick and choose to construct an **efficient** solution.

When approaching a problem it's really, really important to fully understand the problem before trying to solve it. Taking time to understand a problem is analogous to reading the instructions before taking an exam or putting together furniture or a kit of Legos. If you have a solid understanding of data structures, problems will often reveal their own solutions if you take the time to listen and understand them fully.

Data Structures give us a set of building blocks, like Legos, from which we can compose a solution from the bottom up. As we construct a solution, each step builds on every step before it. Weaknesses to our approach will appear as we append steps to our solution. Bottlenecks and dead-ends will appear. Getting all the way to a complete solution necessitates validating each step and adjusting as needed.

Once you've constructed a complete solution, the problem will seem simple and the solution will seem obvious in retrospect. Hindsight is always 20/20.

TODO: Making appropriate assumptions

## Well-Known Problems

If you're interested in seeing algorithms in action, here's a collection of well-known problems with discussion, solutions and code.