> ## Documentation Index
> Fetch the complete documentation index at: https://leetcode-py.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> leetcode-py is a Python LeetCode practice environment generator with one CLI: lcpy. It is not a service or platform.
> Each problem is a directory under leetcode/ with README.md, solution.py, test_solution.py, helpers.py, and playground.ipynb. lcpy gen creates them from JSON templates bundled with the package.
> Examples are backed by tests; copy them verbatim.

# Design Excel Sum Formula Python Solution

> Tested Python solution for LeetCode 631 with 12 pytest cases. Generate a practice environment with lcpy.

LeetCode 631, [Hard](/catalog/hard). Topics: [Graph](/catalog/topics/graph), [Design](/catalog/topics/design), [Topological Sort](/catalog/topics/topological-sort), [Array](/catalog/topics/array), [Hash Table](/catalog/topics/hash-table), [String](/catalog/topics/string), [Matrix](/catalog/topics/matrix). [View on LeetCode](https://leetcode.com/problems/design-excel-sum-formula/description/).

Generate this problem as a practice environment: tested reference solution, 12 [parametrized pytest cases](/practice/testing), and a playground notebook:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
lcpy gen -n 631   # by problem number
lcpy gen -s design_excel_sum_formula   # by problem name
```

## Problem

Design the basic function of **Excel** and implement the function of the sum formula.

Implement the `Excel` class:

* `Excel(int height, char width)` Initializes the object with the `height` and the `width` of the sheet. The sheet is an integer matrix `mat` of size `height x width` with the row index in the range `[1, height]` and the column index in the range `['A', width]`. All the values should be **zero** initially.
* `void set(int row, char column, int val)` Changes the value at `mat[row][column]` to be `val`.
* `int get(int row, char column)` Returns the value at `mat[row][column]`.
* `int sum(int row, char column, List<String> numbers)` Sets the value at `mat[row][column]` to be the sum of cells represented by `numbers` and returns the value at `mat[row][column]`. This sum formula **should exist** until this cell is overlapped by another value or another sum formula. `numbers[i]` could be on the format:
  * `"ColRow"` that represents a single cell. For example, `"F7"` represents the cell `mat[7]['F']`.
  * `"ColRow1:ColRow2"` that represents a range of cells. The range will always be a rectangle where `"ColRow1"` represents the position of the top-left cell, and `"ColRow2"` represents the position of the bottom-right cell.

**Note:** You could assume that there will not be any circular sum reference.

### Examples

```
Input
["Excel", "set", "sum", "set", "get"]
[[3, "C"], [1, "A", 2], [3, "C", ["A1", "A1:B2"]], [2, "B", 2], [3, "C"]]
Output
[null, null, 4, null, 6]

Explanation
Excel excel = new Excel(3, "C");
excel.set(1, "A", 2);
excel.sum(3, "C", ["A1", "A1:B2"]); // return 4
excel.set(2, "B", 2);
excel.get(3, "C"); // return 6
```

### Constraints

* `1 <= height <= 26`
* `'A' <= width <= 'Z'`
* `1 <= row <= height`
* `'A' <= column <= width`
* `-100 <= val <= 100`
* `1 <= numbers.length <= 5`
* `numbers[i]` has the format `"ColRow"` or `"ColRow1:ColRow2"`.
* At most `100` calls will be made to `set`, `get`, and `sum`.

## Solution

Reference implementation from [solution.py on GitHub](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_excel_sum_formula/solution.py), full suite in [test\_solution.py](https://github.com/wislertt/leetcode-py/blob/main/leetcode/design_excel_sum_formula/test_solution.py):

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class Excel:
    # Time: get/sum O(reachable formula graph) per call
    # Space: O(height * width)
    def __init__(self, height: int, width: str) -> None:
        self.height = height
        self.width = ord(width) - 64
        self.contents: dict[tuple[int, int], int | list[str]] = {}

    def set(self, row: int, column: str, val: int) -> None:
        self.contents[(row, ord(column) - 64)] = val

    def get(self, row: int, column: str) -> int:
        return self._value(row, ord(column) - 64)

    def sum(self, row: int, column: str, numbers: list[str]) -> int:
        self.contents[(row, ord(column) - 64)] = numbers
        return self._value(row, ord(column) - 64)

    def _value(self, row: int, col: int) -> int:
        content = self.contents.get((row, col))
        if content is None:
            return 0
        if isinstance(content, int):
            return content
        return sum(self._parse(token) for token in content)

    def _parse(self, token: str) -> int:
        if ":" not in token:
            return self._value(int(token[1:]), ord(token[0]) - 64)
        top_left, bottom_right = token.split(":")
        r1, r2 = int(top_left[1:]), int(bottom_right[1:])
        c1, c2 = ord(top_left[0]) - 64, ord(bottom_right[0]) - 64
        return sum(self._value(r, c) for r in range(r1, r2 + 1) for c in range(c1, c2 + 1))
```

## Complexity

| Time | Space |
| - | - |
| get/sum O(reachable formula graph) per call | O(height \* width) |

## Tags

[NeetCode All](/catalog/neetcode).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.