What algo is optimized for
The previous tutorials showed the mechanics of using the language. This page explains the design choices behind it.
algo is not trying to be a general-purpose language. It is designed for competitive
programming, where the common problems are:
- repetitive input/output boilerplate
- repeated use of the same graph and data-structure patterns
- a need to move quickly without hiding what the final C++ will do
The most important features follow directly from those goals.
1. Problem-shaped I/O
Section titled “1. Problem-shaped I/O”Contest statements usually describe input in a declarative shape: n, then an array,
then m edges, then q queries. algo mirrors that shape:
input: n, m: int edges: [(int, int)][m]That is less code than hand-written cin loops, but it still compiles to ordinary
reads in C++.
2. Builtins for common contest tools
Section titled “2. Builtins for common contest tools”algo treats familiar algorithms and data structures as first-class vocabulary.
input: n, m: int edges: [(int, int, int)][m]
g = wgraph(n, undirected = true)for (u, v, w) in edges: g.add(u, v, w)
d = g.dijkstra(0).distThis is the kind of operation that appears over and over in contest code, so the language provides it directly instead of forcing you to paste a template every time.
The same idea applies to other graph helpers:
g.bfs(src).dist # BFS distances (-1 if unreachable)wg.bellman_ford(src).dist # Bellman-Fordg.topo() # topological orderg.scc() # strongly connected componentswg.mst() # minimum spanning treeAnd to common data structures:
d = dsu(n) # disjoint set uniond.unite(u, v)d.same(u, v)
st = segtree(a, op = max) # segment treest.update(i, val)st.query(l, r)
b = bit(n) # Fenwick treeb.add(i, val)b.sum(l, r)3. Structured syntax for common patterns
Section titled “3. Structured syntax for common patterns”Dynamic programming is repetitive enough to justify dedicated syntax:
input: n, W: int w: [int][n] v: [int][n]
dp[i: 1..n, j: 0..W] -> int, maximize: base: dp[0][j] = 0 <- dp[i-1][j] <- dp[i-1][j-w[i-1]] + v[i-1] where j >= w[i-1]
println dp[n][W]Likewise, reductions and binary search helpers let you express the operation directly:
println max(dp[i] for i in [0, n))println sum(a[i] * b[i] for i in [0, n))ans = bsearch(0, 1_000_000_000, |mid| feasible(mid))These are the kinds of compact forms that matter in a contest setting because they remove setup code, not because they look novel.
4. Generated C++ is still the source of truth
Section titled “4. Generated C++ is still the source of truth”The language only works if you can still trust the lowered code. That is why algo
compiles to readable C++17 instead of hiding everything in a runtime.
When the language is not enough, there is an explicit escape hatch:
cpp: #pragma GCC optimize("O3,unroll-loops")Unknown method calls also pass through to C++:
a.reserve(n)That boundary is important. It keeps the language useful without pretending it can replace every line of contest C++.
5. A few global switches for contest defaults
Section titled “5. A few global switches for contest defaults”One example is #!int64:
#!int64This changes generated C++ so int uses 64-bit storage. It is a deliberate contest
oriented convenience, not a general-language feature.
Summary
Section titled “Summary”If you remember one thing, it should be this:
algois meant to make contest code shorter- not by hiding the solution shape
- but by baking common competitive-programming patterns into the language
Continue with the guides for task-focused docs, or jump to the reference when you need exact forms.