← 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
```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