Feature Creep 2026, 07 - A Mental Math Trainer - Matrices and Prime Multiplicators
Just two more task types this week: I came up with the prime decomposition idea on a whim and it seemed easy enough to add, though not necessarily easy to check against the results. First is a way to get to a number that can be decomposed into primes, which, is technically all numbers by conjecture, but it's not too difficult to create the problem in a way that automatically gives me the solution.
def prime_decomp(self, n):
result = 1
solution_parts = []
for i in range(0, n):
prime = random.choice(self.primes)
solution_parts.append(prime)
result *= random.choice(prime)
return result, solution_parts
This also makes me think that perhaps the problems should generate their solution as return values directly, so that will kinda change how I'll write tests. Perhaps I could make a standard json object with "problem_string" and "solution_string". I'll think about the utility of that sometime in the future. In the end, I can just gather the different solutions, separated by a comma, and compare the sets. That should be easy enough. If python doesn't play well with how I think sets should work, it should also be fast enough to pick apart the result arrays step by step.
Matrix calculation tasks I'll need to be a little careful about. As we know, not every dimension matrix can be added to every other dimension matrix. There's also some interesting properties that we can identify in any given matrix, such as the determinant, or even identifying the degrees of freedom. As such, I need to make sure I need to create a matrix with a set number of columns and rows.
def c_times_r_matrix(self, cols, rows, legal_entries):
ltx = "\\begin{bmatrix}"
for c in range(0, cols):
rowstr = ""
for r in range(0, rows):
rowstr += get_token(self, legal_entries)
if r != rows - 1:
rowstr += "&"
ltx += rowstr
if c != cols -1:
ltx += "\\\\"
return ltx += "\\end{bmatrix}"
This also happens to happens to double as a vector creation function. However, we also see that we're calling a get_token function. This one is meant to decide what kind of token can go in the expressions by checking against legal_entries. This one's gonna be a little difficult to manage, I imagine, because technically we could open it up to recursion on accident.
def get_token(self, legal):
return eval(random.choice(legal))
We would use the matrix function something like this then:
generator.c_times_r_matrix(4, 4, ["get_natural_num(0, 10)", "get_function(\"x\")"])