ts-07-mathjs-evaluate
1.000
Challenge · difficulty 4/5
# Compile and evaluate expressions (mathjs)
Implement **`solution.ts`** using **mathjs** (already installed — import what you need,
e.g. `import { compile } from "mathjs";`).
Export exactly one function:
```ts
export function evaluateAll(expr: string, scopes: Record<string, number>[]): number[];
```
Behavior:
- **Compile the expression once** with mathjs (`compile(expr)`), then evaluate the
compiled expression against **each** scope in `scopes`, in order.
- Return an array of the numeric results (one per scope). Convert each result to a
`number` so the return type is exactly `number[]`.
- An empty `scopes` array returns `[]`.
The expression may reference variables supplied by the scope and may use mathjs built-in
functions (e.g. `sqrt`, `max`, `sin`).
Examples:
```ts
evaluateAll("a^2 + b", [{ a: 3, b: 1 }, { a: 2, b: 5 }]);
// => [10, 9]
evaluateAll("sqrt(x) + max(y, 1)", [{ x: 9, y: 4 }]);
// => [7] // sqrt(9)=3, max(4,1)=4
evaluateAll("a + b", []);
// => []
```
Keep it fully typed (must pass `tsc --noEmit` in strict mode). Do not use `any` in the
public API.
tests/solution.test.ts
import { test } from "node:test";
import { strict as assert } from "node:assert";
import { evaluateAll } from "./solution.ts";
test("evaluates with multiple variables across scopes", () => {
assert.deepEqual(evaluateAll("a^2 + b", [{ a: 3, b: 1 }, { a: 2, b: 5 }]), [10, 9]);
});
test("preserves scope order", () => {
assert.deepEqual(evaluateAll("x * 10", [{ x: 1 }, { x: 2 }, { x: 3 }]), [10, 20, 30]);
});
test("uses built-in functions", () => {
assert.deepEqual(evaluateAll("sqrt(x) + max(y, 1)", [{ x: 9, y: 4 }]), [7]);
});
test("empty scopes returns empty array", () => {
assert.deepEqual(evaluateAll("a + b", []), []);
});
test("single scope", () => {
assert.deepEqual(evaluateAll("2 * a + 1", [{ a: 20 }]), [41]);
});
test("result is a number array", () => {
const out = evaluateAll("a / b", [{ a: 6, b: 2 }, { a: 9, b: 3 }]);
assert.equal(typeof out[0], "number");
assert.deepEqual(out, [3, 3]);
});
test("compiles once and reuses for differing variable values", () => {
const out = evaluateAll("a + b + c", [
{ a: 1, b: 2, c: 3 },
{ a: 10, b: 20, c: 30 },
]);
assert.deepEqual(out, [6, 60]);
});
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.Proposed solution
```ts
import { compile, CompiledExpression } from "mathjs";
export function evaluateAll(expr: string, scopes: Record<string, number>[]): number[] {
const compiled: CompiledExpression = compile(expr);
return scopes.map(scope => Number(compiled.evaluate(scope)));
}
```Test output (stdout)
TAP version 13
# Subtest: evaluates with multiple variables across scopes
ok 1 - evaluates with multiple variables across scopes
---
duration_ms: 1.623674
type: 'test'
...
# Subtest: preserves scope order
ok 2 - preserves scope order
---
duration_ms: 0.19457
type: 'test'
...
# Subtest: uses built-in functions
ok 3 - uses built-in functions
---
duration_ms: 0.490891
type: 'test'
...
# Subtest: empty scopes returns empty array
ok 4 - empty scopes returns empty array
---
duration_ms: 0.093691
type: 'test'
...
# Subtest: single scope
ok 5 - single scope
---
duration_ms: 0.1015
type: 'test'
...
# Subtest: result is a number array
ok 6 - result is a number array
---
duration_ms: 0.12541
type: 'test'
...
# Subtest: compiles once and reuses for differing variable values
ok 7 - compiles once and reuses for differing variable values
---
duration_ms: 0.124371
type: 'test'
...
1..7
# tests 7
# suites 0
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 411.099091
Reasoning (chain-of-thought)
The user wants a TypeScript function `evaluateAll` that:
1. Takes an expression string and an array of scopes (each scope is a Record<string, number>)
2. Compiles the expression once using mathjs's `compile`
3. Evaluates the compiled expression against each scope
4. Returns an array of numbers
Let me write this:
```ts
import { compile, CompiledExpression } from "mathjs";
export function evaluateAll(expr: string, scopes: Record<string, number>[]): number[] {
const compiled = compile(expr);
return scopes.map(scope => Number(compiled.evaluate(scope)));
}
```
This should work. Let me verify:
- `compile(expr)` returns a `CompiledExpression`
- `compiled.evaluate(scope)` evaluates with the given scope
- We convert each result to a `number` using `Number()`
- Empty scopes returns empty array (map on empty array is empty)
- No `any` used
- Fully typed
This looks correct and complete.