Sign in

Slice Copy vs Alias

core

Implement snapshot_after_each(grid, ops): grid is a list of row lists of ints, and each op is a (row, col, val) assignment. Apply the ops in order, and after each one record a snapshot of the whole grid; return the list of snapshots. Each snapshot must show the grid as it was at that moment, untouched by the ops that come later.

The drill is copy versus alias. b = a copies nothing: both names point at the same list, and a mutation through either shows through both. b = a[:] (or list(a)) builds a new outer list, which is a real copy for a flat list of ints. For a grid it is not enough: the slice copies the outer list, but the row objects inside are shared between the copy and the original. A snapshot taken with grid[:] therefore keeps live pointers into the grid's rows, every later grid[r][c] = v rewrites history through them, and by the end all snapshots have quietly converged to the final grid. The first snapshot looks right until the second op lands, which is exactly why the bug survives small tests.

Copy one level deeper than you mutate: the ops assign into rows, so the rows are what need copying. [row[:] for row in grid] rebuilds the outer list and every row; nothing in the snapshot is reachable from grid afterward. (For arbitrarily nested structures the same idea generalizes to copy.deepcopy, but a per-row slice is the idiomatic grid form.)

Example: grid [[0, 0]] with ops (0, 0, 1) then (0, 1, 2) must return [[[1, 0]], [[1, 2]]]. With grid[:] snapshots both entries share the single row object, so the result comes back as [[[1, 2]], [[1, 2]]], the first snapshot mutated after the fact.

Input format: each test in tests/*.in is laid out as:

  • Line 1: r c, the grid's row and column counts.
  • Next r lines: one grid row of c values each.
  • Next line: k, the number of ops.
  • Next k lines: row col val, one assignment per line.

Test 02.in reads:

1 2
0 0
2
0 0 1
0 1 2

This is the statement's own example: a 1 x 2 zero grid with two ops, the smallest test where the second op can rewrite an aliased first snapshot.

Where you'll use it:

✦ Solution & editorial unlock with the pass.

Loading...