Spreadsheet IILoading saved progress…

Spreadsheet II

Build a Spreadsheet class whose cells can hold numbers or formulas, like a stripped-down version of the grid in any spreadsheet app. A formula is a string that begins with = and chains operands together with the binary operators +, -, *, and /. The twist that makes this the "II" version: formulas are evaluated strictly left to right with no operator precedence. =2+3*4 is (2 + 3) * 4 = 20, not the 14 you would get from normal math rules. Operands are either number literals or the names of other cells, and a referenced cell is read fresh every time — so updating a source cell changes everything that depends on it.

Signature

class Spreadsheet {
  // Store a value in a cell. `value` is either a number, or a string.
  // A string that starts with '=' is a FORMULA, kept unparsed until read.
  setCell(name: string, value: number | string): void;

  // Read a cell as a number. A formula is evaluated now (left to right);
  // a reference inside it is resolved by reading that cell, recursively.
  // An unset cell — read directly or referenced — is 0.
  getCell(name: string): number;
}

Examples

const sheet = new Spreadsheet();
sheet.setCell('A1', '=2+3*4');
sheet.getCell('A1'); // → 20   ((2 + 3) * 4), left to right — NOT 14
const sheet = new Spreadsheet();
sheet.setCell('A1', 5);
sheet.setCell('B1', '=A1*2');
sheet.getCell('B1'); // → 10
sheet.setCell('A1', 50); // change the source...
sheet.getCell('B1'); // → 100   B1 re-reads A1 on every get

Notes

  • Left to right, no precedence. This is the whole point. Apply each operator the instant you reach it: =10-2*3+1 folds as ((10 - 2) * 3) + 1 = 25. Multiplication and division get no head start over addition and subtraction.
  • Operands are literals or references. A token is either a number like 2 or 3.5, or a cell name like A1 whose value you read. References resolve recursively — a referenced cell may itself hold a formula.
  • Resolution is lazy. Don't evaluate a formula when it's set; evaluate it when it's read. There is no caching, so a fresh read always reflects the current value of every cell it depends on.
  • Unset cells are 0. Reading a cell that was never set returns 0, and a reference to an unset cell inside a formula also contributes 0.
  • Division is true float division. =7/2 is 3.5, not 3. Use JavaScript's /.
  • Assume references are acyclic. You don't need to detect circular references or cache recomputes — that's a separate problem. Every chain of references you're given terminates.
Loading editor…