PracHub
QuestionsPremiumLearningGuidesCheatsheetNEWCoaches

Quick Overview

This multi-part question evaluates skills in differentiable linear algebra and automatic differentiation safety, memory- and buffer-aware numerical implementation, combinatorial sequence balancing and greedy algorithm design, and numerically stable streaming probability/entropy computation.

  • medium
  • OpenAI
  • Coding & Algorithms
  • Software Engineer

Implement Three Research Coding Tasks

Company: OpenAI

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: HR Screen

Solve the following coding problems. ### 1. Implement a differentiable matrix product You are given a list of `k` square matrices `M1, M2, ..., Mk`, all of shape `n x n`. 1. Implement an in-place routine that computes `M1 @ M2 @ ... @ Mk` while reusing intermediate buffers. 2. Explain why this in-place approach is unsafe for automatic differentiation in a framework with PyTorch-like autograd. 3. Implement an out-of-place version that is compatible with backpropagation. 4. Derive the backward pass manually: given the upstream gradient of the final product, compute the gradient with respect to each input matrix. 5. Re-express both the forward and backward computations using an associative parallel scan similar to the Hillis-Steele prefix-scan. ### 2. Generate a balanced ordering of tagged tasks You have three finite tag sets: `A`, `H`, and `T`. Each task is a triple `(a, h, t)` from the Cartesian product `A x H x T`. Output an ordering of all triples exactly once. For any prefix of the output sequence, define the imbalance of a family of pair buckets as: `max_bucket_count - min_bucket_count` where bucket counts are computed over all pair types in that family. 1. First, construct an ordering whose prefixes keep the `(a, h)` pair counts as balanced as possible. 2. Then strengthen the requirement so that prefixes keep both `(a, h)` and `(a, t)` pair counts as balanced as possible at the same time. 3. Describe or implement a brute-force or greedy algorithm that repeatedly chooses the next unused triple that best improves the current balance. No strict complexity target is required. ### 3. Compute numerically stable streaming entropy Given logits `z = [z1, z2, ..., zn]`, let `p = softmax(z)`. 1. Implement a numerically stable function to compute the entropy `H(p) = -sum_i p_i log p_i`. 2. Rewrite the expression so it can be computed directly from the logits using a log-sum-exp style normalization. 3. Now support a streaming setting where logits arrive one at a time. After each new logit is appended, update the entropy efficiently without recomputing from scratch. 4. Specify which running statistics must be maintained, including how to update them when the current maximum logit changes.

Quick Answer: This multi-part question evaluates skills in differentiable linear algebra and automatic differentiation safety, memory- and buffer-aware numerical implementation, combinatorial sequence balancing and greedy algorithm design, and numerically stable streaming probability/entropy computation.

Part 1: Chain Matrix Product with Manual Backpropagation

Given k square matrices M[0], M[1], ..., M[k-1] of the same size n x n, and an upstream gradient matrix G for the final product P = M[0] @ M[1] @ ... @ M[k-1], return both the final product and the gradient of L = sum(P[i][j] * G[i][j]) with respect to every input matrix. Your implementation must not mutate the input matrices. Use prefix and suffix products (a scan-style idea) so intermediate products can be reused in the backward pass.

Constraints

  • 1 <= k <= 30
  • 1 <= n <= 15
  • All matrices are square and have identical dimensions
  • Matrix entries are integers or floats with absolute value at most 100

Examples

Input: ([[[1, 2], [3, 4]], [[0, 1], [1, 0]]], [[1, 0], [0, 1]])

Expected Output: ([[2, 1], [4, 3]], [[[0, 1], [1, 0]], [[1, 3], [2, 4]]])

Explanation: The final product is M0 @ M1. With identity upstream gradient, each matrix gradient depends only on the product on its left and right.

Input: ([[[1, 0], [0, 2]], [[2, 1], [0, 1]], [[1, 2], [3, 4]]], [[1, 0], [0, 1]])

Expected Output: ([[5, 8], [6, 8]], [[[5, 3], [8, 4]], [[1, 3], [4, 8]], [[2, 0], [1, 2]]])

Explanation: This checks a longer chain and verifies all three gradients.

Input: ([[[5]]], [[7]])

Expected Output: ([[5]], [[[7]]])

Explanation: Edge case: with only one 1x1 matrix, the product is the matrix itself and the gradient equals the upstream gradient.

Input: ([[[1, 0], [0, 1]], [[2, 3], [4, 5]]], [[1, 2], [3, 4]])

Expected Output: ([[2, 3], [4, 5]], [[[8, 14], [18, 32]], [[1, 2], [3, 4]]])

Explanation: The first matrix is identity, so the product is the second matrix. This test uses a non-identity upstream gradient.

Hints

  1. Build prefix products I, M0, M0@M1, ... and suffix products ..., M[i]@...@M[k-1], I.
  2. If P = A @ X @ B and the upstream gradient for P is G, then the gradient for X can be written using transposes of A and B.

Part 2: Greedy Balanced Ordering of Tagged Tasks

There are a * h * t tasks, one for every triple (x, y, z) where 0 <= x < a, 0 <= y < h, and 0 <= z < t. Build an ordering of all triples exactly once. At each step, choose the unused triple that best balances prefix counts for both pair families (x, y) and (x, z). For a family of buckets, imbalance means max_bucket_count - min_bucket_count over all possible buckets in that family, including buckets still at zero. For a candidate next triple, compute the resulting imbalance of the (x, y) buckets and the (x, z) buckets after adding it. Choose the triple with the smallest score: (max(imb_xy, imb_xz), imb_xy + imb_xz, imb_xy, imb_xz, x, y, z). Return the full ordering.

Constraints

  • 1 <= a, h, t <= 5
  • All triples from the Cartesian product must appear exactly once
  • Tie-breaking must follow the exact lexicographic score defined in the statement

Examples

Input: (1, 1, 1)

Expected Output: [(0, 0, 0)]

Explanation: Edge case: there is only one task.

Input: (1, 2, 2)

Expected Output: [(0, 0, 0), (0, 1, 1), (0, 0, 1), (0, 1, 0)]

Explanation: After the first choice, the greedy rule picks the triple that simultaneously fixes both pair-family imbalances.

Input: (2, 1, 2)

Expected Output: [(0, 0, 0), (1, 0, 0), (0, 0, 1), (1, 0, 1)]

Explanation: This case balances the two x-values while also keeping the (x, z) buckets even.

Input: (2, 2, 1)

Expected Output: [(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)]

Explanation: With only one z-value, balancing (x, y) dominates many tie situations.

Hints

  1. Keep separate count tables for the (x, y) buckets and the (x, z) buckets.
  2. Because many candidates can tie, include the triple itself in the comparison score to make the output deterministic.

Part 3: Numerically Stable Streaming Softmax Entropy

Given a list of logits z, compute the entropy of the softmax distribution after every prefix. For each prefix z[0:i], let p be softmax(z[0:i]) and H(p) = -sum(p_j * log(p_j)). Return the entropy for every prefix, rounded to 6 decimal places. Your algorithm must be numerically stable and should update the answer in streaming fashion without recomputing each prefix from scratch.

Constraints

  • 0 <= len(logits) <= 200000
  • Each logit is an integer or float with absolute value at most 1e9
  • Your algorithm should run in O(n) time and O(1) extra space besides the output list

Examples

Input: []

Expected Output: []

Explanation: Edge case: no logits means no prefix entropies.

Input: [0.0]

Expected Output: [0.0]

Explanation: A single logit always produces a probability of 1 and entropy 0.

Input: [0.0, 0.0, 0.0]

Expected Output: [0.0, 0.693147, 1.098612]

Explanation: Uniform softmax over 1, 2, and 3 items has entropies ln(1), ln(2), and ln(3).

Input: [1.0, 2.0]

Expected Output: [0.0, 0.582203]

Explanation: The second prefix is a non-uniform two-class softmax.

Input: [2.0, -1000.0, 2.0]

Expected Output: [0.0, 0.0, 0.693147]

Explanation: This tests numerical stability with a very small probability in the middle.

Hints

  1. Rewrite entropy as logsumexp(z) - sum(p_i * z_i).
  2. Maintain the current maximum logit, the shifted sum of exponentials, and the shifted sum of z_i * exp(z_i - max). If a new maximum arrives, rescale the old running sums.
Last updated: Apr 30, 2026

Loading coding console...

PracHub

Master your tech interviews with 7,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Simulate Infection Spread on a Grid - OpenAI (hard)
  • Implement Social Follow Recommendations - OpenAI (medium)
  • Build a Compose Rating Card - OpenAI (medium)
  • Generate Data Labeling Schedules - OpenAI (medium)
  • Convert IPv4 Ranges to CIDR Blocks - OpenAI (medium)