This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 2 — Side Hustle
What I Built
Every tutor in India who runs a small coaching class has the same weekly chore: find ten new questions for Saturday's
test. Textbook questions are already solved on YouTube. Question banks cost money and still repeat. Asking a chatbot
gives you fresh questions, but you then have to solve each one yourself, because a wrong answer key in front of a
class costs you more than the time you saved.
Dare2Solve Studio writes fresh math puzzles and refuses to hand over any puzzle whose answer it couldn't confirm.
A tutor picks a topic (probability, remainders, time and distance...), an audience (classes 8–10, JEE, olympiad,
placement aptitude) and a difficulty, and gets:
- puzzles that passed two independent checks, stored in a searchable bank that rejects near-duplicates,
- a printable worksheet PDF with a name/score header and an answer key with worked solutions,
- a square "puzzle of the day" card to post in the class WhatsApp group.
Who pays: a tutor or a small coaching centre making weekly tests, at about the price of a pizza a month
(₹299/month in my head). That only works because the model costs nothing to run (more on that below).
Demo
Code
JayPokale
/
dare2solve-studio
Fresh math puzzles a tutor can trust: a local Gemma model writes them, code and a blind re-solve check every answer, Tiger Cloud keeps a deduplicated bank
Dare2Solve Studio
Fresh math puzzles for tutors and coaching classes, with every answer checked by running code It runs an open-weight model (Gemma 4 E4B through Ollama) on your own computer.
Demo (2 minutes): https://youtu.be/MVTBaImAQBc
A tutor picks a topic, an audience (classes 8–10, JEE, olympiad, placement aptitude) and a difficulty. The studio writes new puzzles, rejects every one whose answer it can't confirm, and keeps the rest in a searchable bank. From the bank it prints a worksheet PDF with an answer key, or a square "puzzle of the day" card for WhatsApp or Instagram.
How a puzzle is checked
The model writes five things for each puzzle: the problem, its working notes, a Python solve() function that
computes the answer independently (by brute force where possible), a worked solution, and the answer. The notes get
their own field because a small model otherwise thinks inside the code: dozens…
How I Built It
A model that's wrong a lot, wrapped in checks that aren't
The model is Gemma 4 E4B, running in Ollama on my laptop's 6 GB GTX 1660 Ti. A small model (about
4 billion effective parameters) writes fluent, well-set puzzles, and gets the arithmetic wrong surprisingly often. So the design assumes every
answer is wrong until proven otherwise. For every puzzle the model returns JSON (enforced with Ollama's JSON-schema
format) with the problem, the answer, a worked solution and a Python solve() function, and then:
-
The code check.
solve()must compute the answer on its own, by brute force when possible, and must agree with the stated answer. It runs in a sandbox: an AST whitelist of imports, no dunder attributes, noopen/exec/eval, an empty environment, andRLIMITcaps on CPU, memory, file size and file handles. -
The blind re-solve. The model then sees only the problem text and must first say whether it's well
posed, then solve it again with fresh code. (Its notes go in a separate
reasoningfield; see below for why.) This catches the failure the code check can't: a puzzle that is internally consistent with its own code but contradictory or missing a fact. - A real solution. At least three numbered steps, or it's rejected.
When the model's own arithmetic slips but its program runs, and the blind re-solve agrees with the program, two
independent derivations agree, so the puzzle is kept: the answer is corrected and the solution rewritten for it.
What the checks caught
I ran the pipeline on eight topics, one puzzle each, up to three attempts per puzzle, with Gemma 4 E4B:
8 of 8 topics produced a puzzle that passed every check, and 5 of 13 attempts were discarded on the way
(about 30 minutes on the laptop). The discards are the point. In this run they were:
- two puzzles where the blind re-solve reached a different answer than the original,
- one the blind solver called ill-posed,
- one whose code disagreed with its own stated answer, and
- one whose worked solution had only one step.
Earlier runs also caught solver code that didn't compile and a ₹ sign inside the Python code (the prompt asks
for Indian context with money in ₹; it now asks for ASCII-only code).
Then I checked the checker: I solved all eight puzzles by hand (and brute-forced them). Seven were correct. One
had no solution at all: both the original program and the blind one returned None, and None == None, so the
pipeline counted it as two derivations agreeing. That's fixed: a solve() that returns anything other than a number
now fails. One of the seven also gives its own answer away (it asks for a digit sum it already stated), which no
check catches yet; a tutor would skip that one.
My own bugs were caught too. An output limit of 1,500 tokens silently truncated the JSON in a whole evaluation
round; I threw that round's data away instead of reporting it. And in the round before this one, only 2 of 8 topics
verified. Reading the raw replies showed why: the model was thinking inside solve_code, writing forty lines of
comments ("Wait, let's re-read the problem…") and stopping before the function had a body. The checks rejected it
as a syntax error, correctly, but it wasn't a wrong answer, just nowhere to think. Giving the JSON a separate
reasoning field ahead of the code, and asking for code "not notes", fixed it: the four problems that had failed
this way all produced running code on the next try, and the numbers above are from the rerun with that fix.
A bank that doesn't repeat itself (Tiger Data)
Verified puzzles go into a Tiger Cloud hypertable with a 384-dimensional embedding of the problem text
(bge-small-en-v1.5 via fastembed, also local) and an HNSW index. Before a puzzle is stored, the bank looks up its
nearest neighbour; above 0.92 cosine similarity it's rejected as the same question in different words. The same
index powers "search by meaning", so a tutor can type "probability with coloured balls" and find matching puzzles
regardless of wording. Time-partitioning by creation date keeps "what did I make this month" cheap as the bank grows.
Being kind to a laptop
My laptop froze twice while I was building this, under GPU heat and memory pressure. So the evaluation waits
whenever the GPU is above 78 °C, pauses between puzzles, and the web app runs one generation at a time on one
worker thread. Slow, but a tutor makes a worksheet once a week.
Why Does Open Innovation Matter?
- The business only works at zero marginal cost. Each puzzle takes several model calls (write and re-solve, sometimes a code retry or a rewrite, up to three attempts). On a paid API that's a cost per puzzle that a ₹299/month price can't carry for a tutor making 50 puzzles a week. On an open-weight model on hardware the tutor already owns, it costs electricity.
- Checks matter more than model size. Because I could run the model as many times as I liked, I could afford to distrust it: generate, verify with code, re-solve blind, retry. The open model plus cheap verification beats a bigger model I'd have to trust.
- It works offline and stays private. A tutor's question bank is their product. It never leaves their machine, apart from the optional cloud bank they own.
Prize Categories
- Best Use of Gemma: Gemma 4 E4B writes, solves and re-solves every puzzle, with schema-constrained JSON output.
- Best Use of Tiger Data: the puzzle bank is a Tiger Cloud hypertable with pgvector HNSW search and near-duplicate rejection.
Top comments (0)