The Problem
Discrete mathematics is notation-dense and definition-heavy in a way that punishes passive reading. You can spend an hour reading about propositional logic and still confuse the contrapositive with the converse under exam pressure. You can read the inclusion-exclusion principle three times and still freeze when a counting problem requires it. The gap between understanding something when you see it explained and being able to produce it on demand is wide, and passive reading doesn't close it.
I was working through discrete math material and kept hitting the same wall. I understood each concept in the moment, but the retention wasn't sticking. Flash cards felt low-fidelity for material this notation-heavy. Problem sets from textbooks helped, but they're scattered, slow to self-grade, and give no immediate explanation of why you're wrong.
I needed active recall with instant feedback and explanations. Nothing I found matched that exactly for discrete math at the CS undergraduate level: the right mix of logic, set theory, graph theory, combinatorics, number theory, and relations all in one place with good questions.
So I built Mathemphetamine.
Pivoting From Typesec
Mathemphetamine started as Typesec: a browser-based typing drill I built for security CLI tools. The infrastructure was already there: a topic selection screen, a game loop, session statistics, Cloudflare Workers deployment. The scaffolding was sound. What needed to change was the mechanic and the domain.
Typesec used typing as its core loop because the goal was muscle memory. Typing nmap -sV --script vuln 192.168.1.1 repeatedly builds the motor pattern so you can produce it under pressure. For math, the goal is different. You're not trying to reproduce notation by rote. You're trying to distinguish between similar-sounding concepts, apply definitions correctly, and execute small computations. Multiple choice is the right mechanic for that: it forces you to discriminate between plausible wrong answers rather than just recognise a correct one when you see it explained.
So I stripped out the typing engine entirely and replaced it with a quiz loop. The data shape changed. The UI changed. The aesthetic changed. The deployment infrastructure stayed the same.
Design Constraints
The constraints I imposed were the same as with Typesec, plus one new one:
- No installation: Browser-based, open and drill immediately
- Zero dependencies: Vanilla HTML, CSS, and JavaScript: no framework, no build step
- Immediate answer feedback: Flash the screen on correct or wrong, reveal the right answer if you miss it
- Always show the explanation: Not just whether you were right, but why: that's the actual learning event
- Keyboard-first:
1–4orA–Dto answer,Enterto advance,Escapeto go back - Streak tracking: A running correct streak adds a small competitive element that makes sessions more engaging
The explanation requirement was the one that didn't exist in typesec. A typing drill can get away without explanations because the command and its simulated output carry the teaching content. A quiz question with four options and no explanation is just a test. I wanted a learning tool, not a test.
Implementation
Each topic is a plain JavaScript file exporting an array of question objects:
{
q: "The contrapositive of p → q is:",
choices: ["q → p", "¬p → ¬q", "¬q → ¬p", "¬p → q"],
answer: 2,
explanation: "The contrapositive of p → q is ¬q → ¬p: swap the hypothesis and conclusion, then negate both. It is logically equivalent to the original. Choice A is the converse; choice B is the inverse."
}
The answer field is a zero-based index into choices. The game engine shuffles questions on every session and reshuffles when the deck is exhausted, so you cycle through the full set without repeating before you've seen everything.
The question bank covers six topics: propositional logic and proof techniques, set theory, relations and functions, graph theory, combinatorics, and number theory. That's 150 questions in total. Writing them took the bulk of the work: the code itself is a few hundred lines.
The Redesign Decision
Typesec had a terminal aesthetic: dark green on near-black, monospace fonts, scanline overlays. It suited that project. Security CLI tools live in terminals; the aesthetic reinforced the context.
Mathematical notation does not benefit from that context. Dense Unicode symbols like ∀ ∃ ∈ ⊆ ↔ ¬ are already visually demanding. Rendering them in a phosphor-green monospace font on a dark background makes them harder to read, not more atmospheric. The styling was actively working against the content.
I redesigned the visual layer entirely: white card surfaces on a light gray background, the system font stack (-apple-system, BlinkMacSystemFont, Inter as fallback), Apple's blue (#0071e3) for interactive elements and accents, system green and red for answer feedback. The same information hierarchy, completely different register. The goal was zero visual friction so the notation gets the reader's full attention.
The switch also reflects a genuine difference in what the two tools are for. Typesec is a drill: you want a bit of tension, a bit of pressure. Mathemphetamine is closer to a study aid: you want calm, clarity, and space to actually read the explanation after you get something wrong.
Why This Approach Works
Active recall consistently outperforms passive review for retention. Reading a definition of bijective functions is not the same cognitive act as being shown four options and having to decide which one is correct. The latter forces retrieval; the former allows recognition without retrieval.
The explanations matter as much as the questions. Getting a question wrong and seeing "¬(p ∧ q) ≡ ¬p ∨ ¬q: De Morgan's Law negates the conjunction and flips the connective" is a qualitatively different experience from getting it wrong and just seeing the correct answer highlighted. The explanation is where the learning actually happens. Wrong answers become teaching events rather than just failures.
The shuffle-and-cycle structure provides something close to spaced repetition without the overhead of a full SRS system. You'll see every question in the deck before you repeat any, which distributes practice across the full topic rather than letting you overlearn a few questions while ignoring the rest.
Current State
The project is deployed on Cloudflare Workers using the same wrangler.json setup as typesec. Six topics are live. Two more: algorithms and complexity, and Boolean algebra are in progress.
The question quality is the ongoing work. Writing good multiple choice questions for mathematics is harder than it looks. The wrong answers need to be plausible: common misconceptions, off-by-one errors, similar-sounding concepts, or the question tests recognition rather than understanding. I'm revising questions as I use the tool and notice which ones are too easy or ambiguously worded.
Lessons
Match the mechanic to the learning goal. Typing builds motor memory. Multiple choice builds discriminative recall. I was tempted to keep the typing mechanic because the infrastructure was already there, but it would have been the wrong tool for the job. The extra work of rebuilding the game loop was worth it.
The explanation is the product. A question without an explanation is a test. A question with an explanation is a lesson. These are different things with different values. If I'd shipped without explanations to save time, I would have built something less useful by a meaningful margin.
Aesthetics serve the content. The terminal look was a deliberate choice in typesec that reinforced what the tool was for. Keeping it for a math quiz would have been inertia, not intention. Changing the visual register entirely was the right call. Design decisions should be made relative to the content they frame, not inherited from previous projects by default.
Reuse infrastructure, not aesthetics. The deployment config, the screen system, the shuffle logic, the flash overlay: all carried over cleanly. The fonts, colors, layout patterns, and interaction metaphors were all replaced. That's the right way to build on prior work: abstract the genuinely reusable parts and make fresh decisions about everything else.
Why I'm Documenting This
Mathemphetamine is a small project. But it involves a few decisions I think are worth recording: choosing the right mechanic for a learning goal, recognising when inherited aesthetics are working against you, and building on existing infrastructure without letting it constrain unrelated choices.
I also want a record of the tools I actually use. I built this to study from. If the questions are good (and I'm working on that) it'll compound the same way typesec did: slow accumulation of small practice sessions that add up over time.