Table of Contents
- What is an algorithm? A simple definition
- Everyday examples of algorithms
- Algorithm vs program: what is the difference?
- Question 1: is the algorithm correct?
- Question 2: is the algorithm efficient?
- One of the oldest algorithms still in use
- How to design your own algorithm
- How we teach it
- Frequently asked questions
An algorithm is a clear, step-by-step method for solving a problem, precise enough that anyone following it, or any computer running it, gets the right answer every time. A recipe, the way you do long division, and the instructions a satnav uses to find a route are all algorithms. The word sounds technical, but the idea is one you already use every day.
This guide explains what makes something an algorithm, gives everyday examples, and then shows three short Python programs that reveal the two questions every algorithm has to answer: is it correct, and is it fast? One of them has a bug that looks perfectly reasonable. Every output below comes from actually running the code.
What is an algorithm? A simple definition
An algorithm takes an input, follows a set of steps, and produces an output. To add two large numbers on paper, the input is the two numbers, the steps are "add the rightmost column, carry if needed, move left", and the output is the total. The steps work for any two numbers, which is what makes it an algorithm rather than a single answer.
The word itself comes from the name of Muhammad ibn Musa al-Khwarizmi, a ninth-century mathematician in Baghdad whose books on calculation were translated into Latin. His name became algorismus, the word for doing arithmetic with written numerals, and eventually algorithm.
Everyday examples of algorithms
- A recipe: ingredients in, steps in order, a cake out. A good recipe says "bake for 25 minutes at 180 degrees", not "bake until it seems done".
- Getting dressed: socks before shoes. Order matters, which is one of the key properties of an algorithm.
- Long division: divide, multiply, subtract, bring down, repeat. Our long division guide walks through it step by step.
- Looking up a word in a dictionary: open near the middle, decide which half, repeat. This is the same halving idea you will see in code below.
- A satnav finding a route, a search engine ranking pages, a streaming app suggesting a film: these are algorithms too, just much larger.
Try this with a child
Ask them to write instructions for making a jam sandwich, then follow the instructions exactly as written, and only as written. "Put jam on the bread" might mean putting the whole jar on the loaf. It is funny, and it teaches the most important property of an algorithm faster than any definition: every step must be precise.
Algorithm vs program: what is the difference?
An algorithm is the method. A program is that method written in a particular programming language so a computer can run it. The same algorithm can be written in Python, Java, Scratch or plain English. That is why programmers often plan an algorithm first, in words or pseudocode, before writing any code. Our post on Python and Java shows the same ideas written in two languages.
Question 1: is the algorithm correct?
Here is an algorithm to find the largest number in a list. Start with a "biggest so far" of 0, look at each number, and if it is bigger, remember it. Sounds sensible. Version 2 changes one line: it starts with the first number in the list instead.
def largest_v1(numbers):
biggest = 0
for n in numbers:
if n > biggest:
biggest = n
return biggest
def largest_v2(numbers):
biggest = numbers[0]
for n in numbers[1:]:
if n > biggest:
biggest = n
return biggest
for test in ([3, 9, 4], [12, 5, 30, 8], [-4, -2, -7]):
print(test, "v1:", largest_v1(test), " v2:", largest_v2(test))
[3, 9, 4] v1: 9 v2: 9
[12, 5, 30, 8] v1: 30 v2: 30
[-4, -2, -7] v1: 0 v2: -2
Both versions agree on the first two lists. On a list of negative numbers, version 1 answers 0, a number that is not even in the list, because no negative number is ever bigger than its starting value of 0. Version 2 correctly answers -2. This is why correctness is the first question: an algorithm must work for every valid input, not just the ones you tried. Testing with unusual inputs, like negatives, zero or an empty list, is how programmers find these bugs.
Question 2: is the algorithm efficient?
Two correct algorithms can do very different amounts of work. Think of the game where someone picks a secret number from 1 to 100 and says "higher" or "lower" after each guess. One strategy is to count up: 1, 2, 3 and so on. Another is to always guess the middle of the numbers that are still possible:
def count_up(secret):
guesses = 0
for guess in range(1, 101):
guesses += 1
if guess == secret:
return guesses
def halving(secret):
low, high, guesses = 1, 100, 0
while True:
guesses += 1
guess = (low + high) // 2
if guess == secret:
return guesses
if guess < secret:
low = guess + 1
else:
high = guess - 1
for secret in (7, 50, 73, 100):
print(f"secret {secret:>3}: counting up {count_up(secret):>3} guesses, halving {halving(secret)} guesses")
worst_up = max(count_up(s) for s in range(1, 101))
worst_half = max(halving(s) for s in range(1, 101))
print("worst case over all 100 secrets:", worst_up, "vs", worst_half)
secret 7: counting up 7 guesses, halving 6 guesses
secret 50: counting up 50 guesses, halving 1 guesses
secret 73: counting up 73 guesses, halving 6 guesses
secret 100: counting up 100 guesses, halving 7 guesses
worst case over all 100 secrets: 100 vs 7
Both strategies always find the number, so both are correct. But counting up needs up to 100 guesses, while halving never needs more than 7. The gap grows fast: for numbers up to a million, counting up could take a million guesses, while halving needs at most 20, because 2 to the power 20 is just over a million. This halving algorithm is called binary search, and it is why computers can search enormous sorted lists almost instantly. Our guide to Big O notation shows how programmers describe this difference precisely.
One of the oldest algorithms still in use
Algorithms are much older than computers. Around 300 BC, the Greek mathematician Euclid described a method for finding the greatest common divisor (GCD) of two numbers, the largest number that divides both. The slow way is to try every possible divisor. Euclid's way is to divide, keep the remainder, and repeat:
def gcd_by_trying(a, b):
checks = 0
for d in range(min(a, b), 0, -1):
checks += 1
if a % d == 0 and b % d == 0:
return d, checks
def gcd_euclid(a, b):
steps = 0
while b != 0:
steps += 1
print(f" step {steps}: {a} = {a // b} x {b} + {a % b}")
a, b = b, a % b
return a, steps
print("trying every number:", gcd_by_trying(1071, 462))
print("Euclid:")
print("result:", gcd_euclid(1071, 462))
trying every number: (21, 442)
Euclid:
step 1: 1071 = 2 x 462 + 147
step 2: 462 = 3 x 147 + 21
step 3: 147 = 7 x 21 + 0
result: (21, 3)
Trying every number from 462 downwards took 442 checks to reach 21. Euclid's algorithm got there in 3 steps. It is still used today, for example in the mathematics behind RSA, a widely used form of encryption. If you want to see it applied, our guide to finding the HCF and LCM in Python builds on it, and our post on modular arithmetic explains why remainders are so powerful.
How to design your own algorithm
- Understand the problem. What is the input? What should the output be? Work through one small example by hand.
- Write the steps in plain words. Be as precise as the jam sandwich test demands.
- Test it on paper with a normal case, then an unusual one: zero, negatives, an empty list, the largest possible value.
- Turn it into code and run the same tests.
- Ask if it could do less work. Only after it is correct.
That order, correct first and fast second, is how professional programmers work too. If you want a structured path from here, our guide on how to start learning data structures and algorithms sets out what to learn next.
A program is only as good as the algorithm inside it. Get the steps right, and the code is the easy part.
How we teach it
Algorithms are where the principles on our how we teach page matter most: working out a method before seeing it written down, tracing code line by line until every step can be predicted, and seeing the same problem solved more than one way, just as this post compares counting up with halving. Younger learners can meet algorithms through our Scratch classes, and older students through Python, one to one or in small groups of 5 to 10.
Frequently asked questions
An algorithm is a clear, step-by-step method for solving a problem. It takes an input, follows precise steps in order, and always finishes with an output. A recipe and the method for long division are everyday examples.
Making a jam sandwich, getting dressed, or brushing your teeth are good examples, because the steps must happen in the right order. A fun activity is to write sandwich instructions and have someone follow them exactly as written.
An algorithm is the method, and a program is that method written in a programming language so a computer can run it. The same algorithm can be written in Python, Java, Scratch or plain English.
It should be precise, with each step having one meaning; ordered; finite, so it always finishes; correct for every valid input; and efficient, doing no more work than necessary.
It comes from the name of Muhammad ibn Musa al-Khwarizmi, a ninth-century mathematician in Baghdad. Latin translations of his books on calculation turned his name into algorismus, which became algorithm.
Euclid's algorithm for the greatest common divisor, described around 300 BC, is one of the oldest algorithms still in everyday use. Methods for arithmetic from ancient Babylon and Egypt are older still.
No. Algorithms are about clear, logical steps, and you can learn them with everyday examples before any maths is involved. Working with algorithms often improves maths skills, not the other way round.