PIXELBANKv9.1.0
Menu

Problem Statement

A Docker build reuses a cached layer only while nothing that layer depends on has changed. The moment one layer misses the cache, every layer after it is rebuilt too. This is why COPY . /app placed before RUN pip install turns a 30-second rebuild into a 6-minute one: touching any source file invalidates the copy, and the dependency install downstream of it is thrown away.

Given a Dockerfile as an ordered list of instructions and the set of files that changed in the build context, work out exactly which layers Docker has to rebuild.

Background

Docker's cache rules, simplified to the ones that matter here:

  • A COPY or ADD layer that reads from the build context misses the cache when any of its source paths cover a changed file.
  • A COPY --from=<stage> reads from another build stage, not from the build context, so a changed context file never invalidates it directly.
  • Every other instruction (FROM, RUN, WORKDIR, ENV, CMD, ...) is identical to last time, so it can only be invalidated by cascade.
  • Cascade rule: once a layer misses, all subsequent layers miss as well.

Source-path matching rule for this problem: split the instruction on whitespace. The last operand is the destination; all earlier operands that do not start with -- are sources. A source . (or ./) covers every changed file. Any other source s (after stripping a leading ./ and any trailing /) covers a changed file f when f == s or f starts with s + "/".

Your Task

Implement:

def rebuilt_layers(instructions, changed_files):

Return a list of the 1-based indices of the instructions that are rebuilt, in ascending order. Return [] when the whole build is a cache hit.

Input Format

  • instructions: list of strings, one Dockerfile instruction each, in order.
  • changed_files: list of build-context relative paths (strings) that changed.

Output Format

  • A list of ints β€” the 1-based positions of the rebuilt instructions.

Sample

insts = [
    "FROM python:3.13-slim",
    "WORKDIR /app",
    "COPY . /app",
    "RUN pip install -r requirements.txt",
    'CMD ["python", "app.py"]',
]
print(rebuilt_layers(insts, ["app.py"]))

Output:

[3, 4, 5]

COPY . /app covers app.py, so layer 3 misses; the cascade rule rebuilds 4 and 5 as well β€” including the expensive pip install.

Example:

Input:
insts = ["FROM python:3.13-slim", "WORKDIR /app", "COPY . /app", "RUN pip install -r requirements.txt", 'CMD ["python", "app.py"]']
print(rebuilt_layers(insts, ["app.py"]))
Output:
[3, 4, 5]
Reasoning:

COPY . /app has source ., which covers every changed file, so layer 3 misses the cache. The cascade rule then forces layers 4 and 5 to rebuild, which is why the dependency install re-runs on every source edit. Layers 1 and 2 are untouched and stay cached.

Constraints:

  • 1 <= len(instructions) <= 60
  • 0 <= len(changed_files) <= 50
  • Instruction keywords are uppercase; operands are separated by single spaces
  • Only COPY and ADD read from the build context
  • A COPY --from=<stage> instruction is never invalidated directly by a changed context file
  • Indices in the returned list are 1-based and ascending
solution.py

Test Results

0/0
Run code to see test results.