This is my leetcode repo. It uses zerotrac and CLIST so leetcode questions actually have an Elo rating attached to them, and has drills on an Anki schedule, a directed graph of moves, problems and drills that tries to categorize every leetcode question, a duolingo-style memory decay curve for nodes, and a pretty complex picker algorithm.
The biggest insight so far has been that i've been "grinding" well below my Elo, and it turns out a Carnegie Mellon study of 60k Codeforces users shows that rating gains come from problems at or above the solver's current Elo, and that solving easy problems correlates negatively with rating.
This probably explains why so many leetcode users refer to the infamous "leetcode grind", since leetcode does not let people pick questions that match their current Elo (unlike topcoder).
Every Elo on this page is scored on first sight only: the first time i meet a problem, on a clock. Re-solving a problem i already know is not a game, because part of that win is remembering the answer. The picker keeps its own Elo over every attempt for its own purposes, and that number is higher; it is not shown here. My current Elo moving average (over the last 60 games) is 1669.
The gauge is my Elo gains on problems i've seen for the first time: +81 Elo per 100h. Over the first 60 days i was playing at 1590, over the last 60 at 1752, divided by the hours in between. It's also the number the onsite chart below uses to guess when i get there. The hours chart is the raw Elo against hours over everything, old picking strategy included, so it looks a lot worse.
The blue line is the median rating of my last 50 first sights, the green line is my Elo. The dots are every attempt, repeats included. For about a year the blue line was around 300 points below my Elo. That is the "leetcode grind" of semi randomly walking through problems, hoping for the best. It jumped in September 2026 when the picker started serving problems at my rating, and it now sits at 1669.
Right of the dotted line is a simulation: the picker running on its own for six months, five times over. Grey dots are the problems it would give me, the dashed lines are where the median and the Elo go. The Elo only goes up because the picker serves harder problems, not because i get better. The model assumes i don't, see below.
The study showed a 200 point gain at about 200 problems above one's rating, roughly 800 hours of practice, so 25 Elo per 100 hours. Since my picker algorithm, once reviews are cleared, aims to serve questions at my current Elo, i'm expecting to at least hit those 25 Elo per 100h (over the entire history), and hopefully beat it.
Extrapolating noisy data. What could go wrong.
If the blue line is above 0, i'm performing better than the model expects, and vice versa for under.
Leetcode's python sitecustomize is full of everything one needs for solving, without needing to import much at all. This repo mimics that, and also adds a lot of very useful helpers for DSA solving.
Here's an example of 1926. Nearest Exit from Entrance in Maze:
class Solution:
def nearestExit(self, maze: List[List[str]], entrance: List[int]) -> int:
q = deque([[entrance[0], entrance[1], 0]])
maze[entrance[0]][entrance[1]] = "+"
while q:
x, y, dist = q.popleft()
if is_edge(maze, x, y) and maze[x][y] != "+":
return dist
maze[x][y] = "+"
for nx, ny in nbrs(maze, x, y):
if maze[nx][ny] != "+":
q.append([nx, ny, dist + 1])
return -1I've written a lot, in the past, about how Python's expressive syntax is really helpful for minimal solutions. However i still find some features of the language to be lacking for things one has to do constantly when solving, like getting indices for the neighbours of a cell in a matrix, that are within the bounds of a matrix.. this can consume many lines and minutes of solving.
With this growing library of harness helpers, my solves are starting to read more and more like pseudocode, which has always been one of Python's ideals. Overall i think i have a stronger ability for language than i do for maths / raw solving ability, so for me, creating an expressive set of helpers and treating them like builtins / part of the language itself feels like the natural path.
You can find the full harness in utils/harness/README.md.
This readme is evolving a lot, and currently reads more like a chart dump that a real explanation of the thesis and tooling. This isn't much spending time on carefully drafted technical documentation if the thesis doesn't pay off, which will take some more data. If it looks like it works well, i'll document it in more detail.
This repo literally has one commit for everything i touch, so it's a firehose.
The tooling is close to 100% LLM generated. It is not reviewed by a human (yet). I've built many flashcard type applications and memory aids over the years, so this is a combination of various pre-existing flashcard techniques, adapted for leetcode in a DG. I never sat down and designed this, it evolved over time, and at the time of writing, the tooling is still changing quite a lot. Eventually, i expect tooling commits to reduce significantly, and for commits to only be readmes, solves, drills, and changes to the graph.
This repo may appear over-engineered, and like i'm enjoying the process of building the tooling more than solving. That's not the case. Becoming really good at leetcode / CP takes years and, if done right, turns into a small daily time investment. So the intricacy of the tooling reflects the life expectancy of this repo.
Moreover, when i'm contracting, this repo has to perform exactly right, while my attention priorities change. So i'm using this window of opportunity to get it right.
I currently consider my progress to be wanting. This is a grind. I'm not gifted at solving algorithms on the fly, and need to build a huge memory bank before i start feeling really at ease. In many ways, i'm the ideal user and test subject for this repo.
The vs all rated elo score is flattering, as the pool includes contestants who entered 1 contest then gave up. The one that matters is the vs 20+ contests.