← run

ts-07-mathjs-evaluate

1.000
7/7 tests· math
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
```typescript
import { compile } from "mathjs";

export function evaluateAll(expr: string, scopes: Record<string, number>[]): number[] {
    if (scopes.length === 0) {
        return [];
    }
    
    const compiledExpr = compile(expr);
    return scopes.map(scope => {
        const result = compiledExpr.evaluate(scope);
        // Convert to number to ensure the return type is exactly number[]
        return Number(result);
    });
}
```

Test output (stdout)

TAP version 13
# Subtest: evaluates with multiple variables across scopes
ok 1 - evaluates with multiple variables across scopes
  ---
  duration_ms: 1.604466
  type: 'test'
  ...
# Subtest: preserves scope order
ok 2 - preserves scope order
  ---
  duration_ms: 0.20326
  type: 'test'
  ...
# Subtest: uses built-in functions
ok 3 - uses built-in functions
  ---
  duration_ms: 0.478191
  type: 'test'
  ...
# Subtest: empty scopes returns empty array
ok 4 - empty scopes returns empty array
  ---
  duration_ms: 0.04922
  type: 'test'
  ...
# Subtest: single scope
ok 5 - single scope
  ---
  duration_ms: 0.11832
  type: 'test'
  ...
# Subtest: result is a number array
ok 6 - result is a number array
  ---
  duration_ms: 0.120941
  type: 'test'
  ...
# Subtest: compiles once and reuses for differing variable values
ok 7 - compiles once and reuses for differing variable values
  ---
  duration_ms: 0.11562
  type: 'test'
  ...
1..7
# tests 7
# suites 0
# pass 7
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms 393.612852