Batch and Pad Variable-Length Vectors with Optional Final-Batch Dropping
Company: Siemens
Role: Machine Learning Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Implement a deterministic data pipeline that groups variable-length integer vectors into batches, pads each retained batch, and optionally drops the final incomplete batch.
The exercise models three responsibilities: `create_data_iterator` groups vectors in input order, `pad_vector_collate` right-pads one batch to its longest vector, and `run_data_pipeline` returns the collected batches. Only the final function is the console entry point; internal helper organization is up to you.
### Function Signature
`run_data_pipeline(vectors: list[list[int]], batch_size: int, pad_value: int, drop_last: bool) -> list[list[list[int]]]`
### Rules
- Read vectors in their original order without shuffling or mutation.
- Form consecutive groups of `batch_size` vectors.
- If the final group contains fewer vectors and `drop_last` is true, discard that entire group. Otherwise retain it.
- For each retained group, let `L` be the greatest original vector length in that group. Append `pad_value` to each vector until its length is `L`.
- Padding is batch-local, not based on the longest vector in the whole dataset.
- Empty vectors are valid. A retained batch containing only empty vectors contains the same number of empty vectors after padding.
These padding direction, pad-value input, ordering, and incomplete-batch rules are explicit conventions for this exercise.
### Output
Return the padded batches in input order. Return `[]` if no batch is retained.
### Constraints
- `0 <= len(vectors) <= 10000`.
- `1 <= batch_size <= 1000`.
- `0 <= len(vector) <= 1000` for each vector.
- Vector elements and `pad_value` are integers in `[-1000000, 1000000]`.
- The total number of input elements and the total number of elements after padding are each at most `1000000`.
- All input arguments are valid.
### Examples
Input: `vectors = [[1,2],[3],[],[4,5,6],[7]], batch_size = 2, pad_value = 0, drop_last = false`
Output: `[[[1,2],[3,0]],[[0,0,0],[4,5,6]],[[7]]]`
With the same arguments except `drop_last = true`, output: `[[[1,2],[3,0]],[[0,0,0],[4,5,6]]]`
Input: `vectors = [[],[]], batch_size = 2, pad_value = -1, drop_last = true`
Output: `[[[],[]]]`
Input: `vectors = [], batch_size = 3, pad_value = 0, drop_last = false`
Output: `[]`
Overview: Build an ordered vector data pipeline with batch-local right padding, empty-vector handling, and optional dropping of the final incomplete batch.
Read the full Siemens Machine Learning Engineer interview experience this question came from
Implement a deterministic data pipeline that groups variable-length integer vectors into batches, pads each retained batch, and optionally drops the final incomplete batch.
The exercise models three responsibilities: grouping the vectors in input order, right-padding one batch to its longest vector, and returning the collected batches. Only `run_data_pipeline` is the console entry point; how you organize any internal helpers is up to you.
### Rules
1. Read the vectors in their original order, without shuffling or mutating them.
2. Form consecutive groups of `batch_size` vectors: the first `batch_size` vectors, then the next `batch_size`, and so on.
3. If the final group contains fewer than `batch_size` vectors and `drop_last` is true, discard that entire group. Otherwise retain it.
4. For each retained group, let `L` be the greatest original vector length in that group. Append `pad_value` to each vector of the group until its length is exactly `L`. Padding is appended on the right, never prepended.
5. Padding is batch-local: `L` is the longest vector of that group only, not the longest vector of the whole dataset.
6. Empty vectors are valid. A retained batch containing only empty vectors has `L = 0`, so it contains the same number of empty vectors after padding.
These padding-direction, pad-value, ordering, and incomplete-batch rules are explicit conventions of this exercise.
### Output
Return the padded batches as a list of batches, in input order. Return `[]` if no batch is retained.
Every value that crosses the boundary is an element or `pad_value` in `[-1000000, 1000000]`; no value can exceed 2^31 - 1, so Java `int` and C++ `int` are sufficient (no `long`/`long long` is needed).
### Examples
Example 1: `vectors = [[1, 2], [3], [], [4, 5, 6], [7]]`, `batch_size = 2`, `pad_value = 0`, `drop_last = False`.
Output: `[[[1, 2], [3, 0]], [[0, 0, 0], [4, 5, 6]], [[7]]]`.
The groups are `[[1,2],[3]]` with `L = 2`, `[[],[4,5,6]]` with `L = 3`, and the final short group `[[7]]` with `L = 1`, which is retained because `drop_last` is false. With the same arguments except `drop_last = True`, the output is `[[[1, 2], [3, 0]], [[0, 0, 0], [4, 5, 6]]]` because the final group holds fewer than `batch_size` vectors.
Example 2: `vectors = [[], []]`, `batch_size = 2`, `pad_value = -1`, `drop_last = True`.
Output: `[[[], []]]`. The single group is full, its greatest length is 0, so no padding is appended.
Constraints
- 0 <= len(vectors) <= 10000.
- 1 <= batch_size <= 1000.
- 0 <= len(vector) <= 1000 for each vector.
- Vector elements and pad_value are integers in [-1000000, 1000000].
- The total number of input elements and the total number of elements after padding are each at most 1000000.
- drop_last is a boolean.
- All input arguments are valid.
- No value crossing the interface can exceed 2^31 - 1, so 32-bit integers suffice in every language.
Examples
Input: ([], 3, 0, False)
Expected Output: []
Explanation: Minimum valid input: no vectors means no group is formed, so the result is empty even when drop_last is false.
Input: ([], 3, 0, True)
Expected Output: []
Explanation: Empty input with drop_last true also yields no batches; there is nothing to drop.
Hints
- Only one group can ever be incomplete. Which one is it, and what does that tell you about when the drop_last test actually has to run?
- The pad target L is defined by the original lengths inside a single group, so decide L before you write any padding and make sure a group cannot see padding produced for an earlier group.
- Work through the cases the rules single out: an empty vectors list, a batch whose vectors are all empty, and an empty vector sitting next to a long one in the same batch.