TopGit tracks srush/Tensor-Puzzles on GitHub as part of the AI Tools family. The project has 4.3k stars. Solve puzzles. Improve your pytorch.
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
When learning a tensor programming language like PyTorch or Numpy it
is tempting to rely on the standard library (or more honestly
StackOverflow) to find a magic function for everything. But in
practice, the tensor language is extremely expressive, and you can
do most things from first principles and clever use of broadcasting.
This is a collection of 21 tensor puzzles. Like chess puzzles these are
not meant to simulate the complexity of a real program, but to practice
in a simplified environment. Each puzzle asks you to reimplement one
function in the NumPy standard library without magic.
I recommend running in Colab. Click here and copy the notebook to get start.
If you are interested, there is also a youtube walkthrough of the puzzles
from lib import draw_examples, make_test, run_test
import torch
import numpy as np
from torchtyping import TensorType as TT
tensor = torch.tensor
Rules
These puzzles are about broadcasting. Know this rule.
Each puzzle needs to be solved in 1 line (<80 columns) of code.
You are allowed @, arithmetic, comparison, shape, any indexing (e.g. a[:j], a[:, None], a[arange(10)]), and previous puzzle functions.
You are not allowed anything else. No view, sum, take, squeeze, tensor.
You can start with these two functions:
def arange(i: int):
"Use this function to replace a for-loop."
return torch.tensor(range(i))
draw_examples("arange", [{"" : arange(i)} for i in [5, 3, 9]])
# Example of broadcasting.
examples = [(arange(4), arange(5)[:, None]) ,
(arange(3)[:, None], arange(2))]
draw_examples("broadcast", [{"a": a, "b":b, "ret": a + b} for a, b in examples])
def where(q, a, b):
"Use this function to replace an if-statement."
return (q * a) + (~q) * b
# In diagrams, orange is positive/True, where is zero/False, and blue is negative.
examples = [(tensor([False]), tensor([10]), tensor([0])),
(tensor([False, True]), tensor([1, 1]), tensor([-10, 0])),
(tensor([False, True]), tensor([1]), tensor([-10, 0])),
(tensor([[False, True], [True, False]]), tensor([1]), tensor([-10, 0])),
(tensor([[False, True], [True, False]]), tensor([[0], [10]]), tensor([-10, 0])),
]
draw_examples("where", [{"q": q, "a":a, "b":b, "ret": where(q, a, b)} for q, a, b in examples])
Puzzle 1 - ones
Compute ones - the vector of all ones.
def ones_spec(out):
for i in range(len(out)):
out[i] = 1
def ones(i: int) -> TT["i"]:
raise NotImplementedError
test_ones = make_test("one", ones, ones_spec, add_sizes=["i"])
# run_test(test_ones)
Puzzle 2 - sum
Compute sum - the sum of a vector.
def sum_spec(a, out):
out[0] = 0
for i in range(len(a)):
out[0] += a[i]
def sum(a: TT["i"]) -> TT[1]:
raise NotImplementedError
test_sum = make_test("sum", sum, sum_spec)
# run_test(test_sum)
Puzzle 3 - outer
Compute outer - the outer product of two vectors.
def outer_spec(a, b, out):
for i in range(len(out)):
for j in range(len(out[0])):
out[i][j] = a[i] * b[j]
def outer(a: TT["i"], b: TT["j"]) -> TT["i", "j"]:
raise NotImplementedError
test_outer = make_test("outer", outer, outer_spec)
# run_test(test_outer)
Puzzle 4 - diag
Compute diag - the diagonal vector of a square matrix.
def diag_spec(a, out):
for i in range(len(a)):
out[i] = a[i][i]
def diag(a: TT["i", "i"]) -> TT["i"]:
raise NotImplementedError
test_diag = make_test("diag", diag, diag_spec)
# run_test(test_diag)
Puzzle 5 - eye
Compute eye - the identity matrix.
def eye_spec(out):
for i in range(len(out)):
out[i][i] = 1
def eye(j: int) -> TT["j", "j"]:
raise NotImplementedError
test_eye = make_test("eye", eye, eye_spec, add_sizes=["j"])
# run_test(test_eye)
Puzzle 6 - triu
Compute triu - the upper triangular matrix.
def triu_spec(out):
for i in range(len(out)):
for j in range(len(out)):
if i <= j:
out[i][j] = 1
else:
out[i][j] = 0
def triu(j: int) -> TT["j", "j"]:
raise NotImplementedError
test_triu = make_test("triu", triu, triu_spec, add_sizes=["j"])
# run_test(test_triu)
Puzzle 7 - cumsum
Compute cumsum - the cumulative sum.
def cumsum_spec(a, out):
total = 0
for i in range(len(out)):
out[i] = total + a[i]
total += a[i]
def cumsum(a: TT["i"]) -> TT["i"]:
raise NotImplementedError
test_cumsum = make_test("cumsum", cumsum, cumsum_spec)
def flatten_spec(a, out):
k = 0
for i in range(len(a)):
for j in range(len(a[0])):
out[k] = a[i][j]
k += 1
def flatten(a: TT["i", "j"], i:int, j:int) -> TT["i * j"]:
raise NotImplementedError
test_flatten = make_test("flatten", flatten, flatten_spec, add_sizes=["i", "j"])
# run_test(test_flatten)
Puzzle 18 - linspace
Compute linspace
def linspace_spec(i, j, out):
for k in range(len(out)):
out[k] = float(i + (j - i) * k / max(1, len(out) - 1))
def linspace(i: TT[1], j: TT[1], n: int) -> TT["n", float]:
raise NotImplementedError
test_linspace = make_test("linspace", linspace, linspace_spec, add_sizes=["n"])
# run_test(test_linspace)
Puzzle 19 - heaviside
Compute heaviside
def heaviside_spec(a, b, out):
for k in range(len(out)):
if a[k] == 0:
out[k] = b[k]
else:
out[k] = int(a[k] > 0)
def heaviside(a: TT["i"], b: TT["i"]) -> TT["i"]:
raise NotImplementedError
test_heaviside = make_test("heaviside", heaviside, heaviside_spec)
# run_test(test_heaviside)
Puzzle 20 - repeat (1d)
Compute repeat
def repeat_spec(a, d, out):
for i in range(d[0]):
for k in range(len(a)):
out[i][k] = a[k]
def constraint_set(d):
d["d"][0] = d["return"].shape[0]
return d
def repeat(a: TT["i"], d: TT[1]) -> TT["d", "i"]:
raise NotImplementedError
test_repeat = make_test("repeat", repeat, repeat_spec, constraint=constraint_set)
Puzzle 21 - bucketize
Compute bucketize
def bucketize_spec(v, boundaries, out):
for i, val in enumerate(v):
out[i] = 0
for j in range(len(boundaries)-1):
if val >= boundaries[j]:
out[i] = j + 1
if val >= boundaries[-1]:
out[i] = len(boundaries)
def constraint_set(d):
d["boundaries"] = np.abs(d["boundaries"]).cumsum()
return d
def bucketize(v: TT["i"], boundaries: TT["j"]) -> TT["i"]:
raise NotImplementedError
test_bucketize = make_test("bucketize", bucketize, bucketize_spec,
constraint=constraint_set)
Speed Run Mode!
What is the smallest you can make each of these?
import inspect
fns = (ones, sum, outer, diag, eye, triu, cumsum, diff, vstack, roll, flip,
compress, pad_to, sequence_mask, bincount, scatter_add)
for fn in fns:
lines = [l for l in inspect.getsource(fn).split("\n") if not l.strip().startswith("#")]
if len(lines) > 3:
print(fn.__name__, len(lines[2]), "(more than 1 line)")
else:
print(fn.__name__, len(lines[1]))
How active is development on srush/Tensor-Puzzles?
The most recent commit recorded on srush/Tensor-Puzzles was 2.1 years ago, based on the GitHub push timestamp. The repository has 392 forks — one of the better signals of community interest.
How many stars does srush/Tensor-Puzzles have?
srush/Tensor-Puzzles has 4.3k GitHub stars — refresh the page for the live number, or check github.com/srush/Tensor-Puzzles. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
Is srush/Tensor-Puzzles open source?
Yes — srush/Tensor-Puzzles ships under the MIT license, which makes its source code freely readable (and, depending on license terms, forkable and reusable). Source: github.com/srush/Tensor-Puzzles.
What else is in the AI Tools space?
srush/Tensor-Puzzles is tracked by TopGit under the AI Tools category, alongside 3 GitHub-tagged topics. Trending and Topics pages list peer repositories of comparable stars and language.
What is srush/Tensor-Puzzles?
srush/Tensor-Puzzles (srush/Tensor-Puzzles) is a Jupyter Notebook project on GitHub. From the project's own README: Solve puzzles. Improve your pytorch.
What language is srush/Tensor-Puzzles written in?
srush/Tensor-Puzzles is written primarily in Jupyter Notebook. GitHub's language field is based on the largest share of bytes in the default branch.
What license does srush/Tensor-Puzzles use?
srush/Tensor-Puzzles is released under the MIT license. Always verify the LICENSE file directly on GitHub for the authoritative terms — license strings can be edited out of sync with a project's actual stance.
Where do I read more about srush/Tensor-Puzzles?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/srush/Tensor-Puzzles is the definitive source.
Read full README in the tab above.
Is Tensor-Puzzles worth your time?
ChatGPT, Claude and Perplexity can all read this page. Ask one of them what it makes of Tensor-Puzzles.