Generate outputs for images and pipelines
Company: Anthropic
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates algorithmic and systems engineering skills related to batch image processing, parallelization, I/O versus CPU trade-offs, and deterministic output association within the Coding & Algorithms domain.
Constraints
- 0 <= len(image_paths), len(pipelines)
- A pipeline may be empty
- All paths in `image_paths` exist in `image_store`
- The total number of operations across all pipelines is at most 2 * 10^5
- The returned list has exactly `len(image_paths) * len(pipelines)` entries, so any solution must spend at least O(m*n) time to build the output
Examples
Input: (['a.png', 'b.png'], {'a.png': 2, 'b.png': 5}, [[('ADD', 3), ('MUL', 2)], [('NEG',), ('SUB', 4)]], 'out')
Expected Output: [('out/img0_pipe0.png', 10), ('out/img0_pipe1.png', -6), ('out/img1_pipe0.png', 16), ('out/img1_pipe1.png', -9)]
Explanation: For `a.png` (value 2), pipeline 0 gives `(2 + 3) * 2 = 10` and pipeline 1 gives `-2 - 4 = -6`. For `b.png` (value 5), the results are 16 and -9.
Input: (['x', 'x', 'y'], {'x': -3, 'y': 0}, [[], [('MUL', -1), ('ADD', 2)], [('SUB', 5), ('NEG',)]], 'res')
Expected Output: [('res/img0_pipe0.png', -3), ('res/img0_pipe1.png', 5), ('res/img0_pipe2.png', 8), ('res/img1_pipe0.png', -3), ('res/img1_pipe1.png', 5), ('res/img1_pipe2.png', 8), ('res/img2_pipe0.png', 0), ('res/img2_pipe1.png', 2), ('res/img2_pipe2.png', 5)]
Explanation: The first pipeline is empty, so it leaves values unchanged. The same path `x` appears twice, so outputs are produced twice with different image indices.
Input: ([], {}, [[('ADD', 1)]], 'tmp')
Expected Output: []
Explanation: There are no images, so no outputs are generated.
Input: (['z'], {'z': 4}, [[('ADD', 1), ('MUL', 3), ('NEG',), ('SUB', 2)]], 'tmp/')
Expected Output: [('tmp/img0_pipe0.png', -17)]
Explanation: The operations are applied in order: `4 -> 5 -> 15 -> -15 -> -17`. A trailing slash in `output_dir` should not change the final file name format.
Solution
def solution(image_paths, image_store, pipelines, output_dir):
transforms = []
for pipeline in pipelines:
a, b = 1, 0
for op in pipeline:
name = op[0]
if name == 'ADD':
b += op[1]
elif name == 'SUB':
b -= op[1]
elif name == 'MUL':
factor = op[1]
a *= factor
b *= factor
elif name == 'NEG':
a = -a
b = -b
else:
raise ValueError(f'Unsupported operation: {name}')
transforms.append((a, b))
loaded = {}
base = output_dir.rstrip('/')
result = []
for i, path in enumerate(image_paths):
if path not in loaded:
loaded[path] = image_store[path]
value = loaded[path]
for j, (a, b) in enumerate(transforms):
out_path = f'{base}/img{i}_pipe{j}.png' if base else f'img{i}_pipe{j}.png'
result.append((out_path, a * value + b))
return resultTime complexity: O(u + P + m*n), where `u` is the number of distinct image paths and `P` is the total number of operations across all pipelines. Space complexity: O(u + n) auxiliary space, excluding the returned output list.
Hints
- Each supported operation keeps the form `a*x + b`. Try compressing each whole pipeline into one pair `(a, b)` before processing the images.
- If the same path appears more than once in `image_paths`, cache its loaded value so you do not conceptually decode it multiple times.