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 } from "mathjs";
export function evaluateAll(expr: string, scopes: Record<string, number>[]): number[] {
const compiled = 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.60921 type: 'test' ... # Subtest: preserves scope order ok 2 - preserves scope order --- duration_ms: 0.193382 type: 'test' ... # Subtest: uses built-in functions ok 3 - uses built-in functions --- duration_ms: 0.475643 type: 'test' ... # Subtest: empty scopes returns empty array ok 4 - empty scopes returns empty array --- duration_ms: 0.086201 type: 'test' ... # Subtest: single scope ok 5 - single scope --- duration_ms: 0.099901 type: 'test' ... # Subtest: result is a number array ok 6 - result is a number array --- duration_ms: 0.128991 type: 'test' ... # Subtest: compiles once and reuses for differing variable values ok 7 - compiles once and reuses for differing variable values --- duration_ms: 0.114861 type: 'test' ... 1..7 # tests 7 # suites 0 # pass 7 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 394.523352