Skip to content

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.

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++.

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).dist

This 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-Ford
g.topo() # topological order
g.scc() # strongly connected components
wg.mst() # minimum spanning tree

And to common data structures:

d = dsu(n) # disjoint set union
d.unite(u, v)
d.same(u, v)
st = segtree(a, op = max) # segment tree
st.update(i, val)
st.query(l, r)
b = bit(n) # Fenwick tree
b.add(i, val)
b.sum(l, r)

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:

#!int64

This changes generated C++ so int uses 64-bit storage. It is a deliberate contest oriented convenience, not a general-language feature.

If you remember one thing, it should be this:

  • algo is 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.