Python challenges

Small problems to practise on, from easy to hard. Your code is checked automatically in the browser. Hints are there when you are stuck, and a reference solution when you are done. New to Python? Do the first few Python lessons first.

0 of 34 solved
0% complete

Basics

Loops, strings and conditions. The first four Python lessons cover everything you need.

0 of 8 solved

Core

Dictionaries, sorting, recursion and classic algorithms. Expect to think for a few minutes before typing.

0 of 11 solved

Caesar cipher

Write caesar(text, shift) that shifts every letter by shift positions in the alphabet, wrapping around from z to a. Preserve case; leave spaces, digits and punctuation untouched.

stringsord/chr4 checks

Anagram check

Write are_anagrams(a, b) that returns True when the two strings use exactly the same letters, ignoring case and spaces.

stringssorting4 checks

Most common words

Write top_words(text, n) that returns the n most frequent words as a list of (word, count) tuples, most frequent first. Compare words case-insensitively and strip punctuation. Break ties alphabetically.

dictssorting3 checks

Sieve of Eratosthenes

Write primes_up_to(limit) that returns a list of all prime numbers ≤ limit, using the sieve: mark multiples of each prime as composite rather than testing each number individually.

algorithmsnumbers3 checks

Two sum

Write two_sum(numbers, target) that returns the indices of the two numbers that add up to target, as a tuple (i, j) with i < j. Assume exactly one answer exists. Aim for a single pass using a dictionary.

dictsalgorithms3 checks

Run-length encoding

Write encode(text) that compresses runs of repeated characters into the character followed by its count, and decode(encoded) that reverses it. Assume the input contains no digits.

strings4 checks

Transpose a matrix

Write transpose(matrix) that flips a list-of-lists over its diagonal: rows become columns. The matrix may be non-square.

listscomprehensions4 checks

Roman numerals

Write to_roman(n) for 1 ≤ n ≤ 3999. Remember the subtractive forms: 4 is IV, 9 is IX, 40 is XL, 90 is XC, 400 is CD, 900 is CM.

numbersstrings4 checks

Binary search

Write binary_search(sorted_list, target) that returns the index of target, or -1 if absent. Halve the search range each step; do not scan linearly.

algorithms5 checks

Balanced brackets

Write is_balanced(s) that returns True if every opening bracket ( [ { is closed by the matching type in the correct order. Ignore any other characters.

stacksstrings4 checks

Flatten anything

Write flatten(nested) that turns arbitrarily nested lists into one flat list, preserving order. Non-list items are kept as they are.

recursionlists4 checks

Intermediate

Data structures, parsers and decorators. Each one is a small piece of real software.

0 of 7 solved

Group anagrams

Write group_anagrams(words) that groups words which are anagrams of each other. Return a list of groups (each a list, in original order), with the groups ordered by their first appearance.

dictssorting3 checks

Merge intervals

Write merge_intervals(intervals), where each interval is a [start, end] list. Merge every pair that overlaps or touches and return the result sorted by start.

sortingalgorithms4 checks

Build an LRU cache

Implement LRUCache(capacity) with get(key) and put(key, value). get returns the value or -1 if missing, and marks the key as recently used. put inserts or updates; when the cache is over capacity, evict the least recently used key. Python dicts remember insertion order, which is all you need.

classesdata structures4 checks

Spiral order

Write spiral(matrix) that returns the elements of a 2-D list in clockwise spiral order, starting from the top-left corner.

listsalgorithms4 checks

Write memoize

Write a decorator memoize that caches results by positional arguments, and exposes the number of cache hits as func.hits. Then use it on the slow recursive count_paths(rows, cols) so that count_paths(16, 16) returns instantly.

decoratorsclosures4 checks

Expression calculator

Write evaluate(expr) that computes an arithmetic expression given as a string, supporting + - * /, parentheses, decimal numbers and the usual precedence. Do not use eval().

parsingrecursion5 checks

Inventory report

Given a list of Item dataclasses, write report(items) that returns a multi-line string: one line per item as NAME padded to 12 chars, quantity right-aligned in 4, and total value (qty × price) right-aligned in 9 with two decimals; then a final line TOTAL followed by the grand total in the same 9-wide column. Sort items by name.

dataclassesformatting3 checks

Advanced

Simulations, graphs, tries and parsers. Sketch a plan on paper before you start.

0 of 8 solved

Conway's Game of Life

Write step(grid) that returns the next generation of a Game of Life grid (a list of lists of 0/1). A live cell with two or three live neighbours survives; a dead cell with exactly three comes alive; everything else dies. Cells outside the grid count as dead.

gridssimulation4 checks

Topological sort

Write build_order(deps) where deps maps each task to the list of tasks it depends on. Return a list containing every task exactly once, such that each task comes after all of its dependencies. Raise ValueError if there is a cycle. When several orders are valid, any one is accepted.

graphsalgorithms4 checks

Trie autocomplete

Implement Trie with insert(word), contains(word) and starts_with(prefix), which returns every inserted word beginning with the prefix in alphabetical order. Store the words in a tree of dictionaries, one level per character.

classesdata structures4 checks

Word wrap

Write wrap(text, width) that breaks text into lines no longer than width characters, breaking only at spaces, greedily fitting as many words per line as possible. Words longer than width go on their own line unbroken. Return the list of lines.

stringsgreedy4 checks

Flatten JSON

Write flatten_json(obj) that turns nested dicts and lists into a single-level dict whose keys are dotted paths. List elements use their index as a key segment. Scalars keep their values.

recursiondicts4 checks

Sudoku validator

Write is_valid_sudoku(board) for a 9×9 grid of integers where 0 means empty. Return True if no row, column or 3×3 box contains a repeated digit 1–9. Empty cells never conflict.

gridssets5 checks

Dijkstra's shortest path

Write shortest_path(graph, start, end) for a weighted graph given as {node: {neighbour: weight}}. Return (distance, path) with the path as a list of nodes, or (None, []) if end is unreachable. Use heapq for the priority queue.

graphsheapq5 checks

Mini Markdown

Write to_html(md) that converts a tiny Markdown subset: lines starting with # or ## become <h1>/<h2>; lines starting with "- " form a <ul> of <li>; any other non-empty line is a <p>. Inline, **bold** becomes <strong> and *italic* becomes <em>. Blank lines separate blocks. Return the HTML lines joined with newlines.

parsingstrings5 checks