Solution
ID: past-exam-of-the-computer-science-course-of-the-university-of-oxford/2015/object-oriented-programming/3/e/solution
Past exam of the computer science course of the University of Oxford 2015 Object oriented programming 3 e Solution by
Codex 0 2026-10-31
Brick boundaries are not observable in the requested row equality. Two adjacent red width-one bricks must compare equal to one red width-two brick at the same left coordinate. Comparing the underlying placement lists would therefore give the wrong result.
Instead build each row's unique sequence of maximal occupied colour runs: merge adjacent placements exactly when they touch and have equal colours. Gaps remain gaps, and touching different colours remain separate runs. This is a geometric version of run-length encoding, with explicit start and end coordinates. Insert these members inside
Row from part (d):private static final class Run {
final long x, end;
final Color colour;
Run(long x, long end, Color colour) {
this.x = x;
this.end = end;
this.colour = colour;
}
}
private List<Run> runs() {
List<Run> result = new ArrayList<Run>();
for (Placed b : bricks) {
int last = result.size() - 1;
if (last >= 0) {
Run r = result.get(last);
if (r.end == b.x && r.colour.equals(b.colour)) {
result.set(last, new Run(r.x, b.end, r.colour));
continue;
}
}
result.add(new Run(b.x, b.end, b.colour));
}
return result;
}
@Override public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof Row)) return false;
List<Run> a = runs(), b = ((Row) other).runs();
if (a.size() != b.size()) return false;
for (int i = 0; i < a.size(); ++i) {
Run r = a.get(i), s = b.get(i);
if (r.x != s.x || r.end != s.end || !r.colour.equals(s.colour))
return false;
}
return true;
}
@Override public int hashCode() {
int h = 1;
for (Run r : runs()) {
h = 31 * h + Long.hashCode(r.x);
h = 31 * h + Long.hashCode(r.end);
h = 31 * h + r.colour.hashCode();
}
return h;
}Color.equals compares colour values rather than object identity. Two row snapshots compare their local horizontal content independently of which wall height supplied them. Empty rows compare equal, even if obtained from different walls. The hash code uses the same canonical runs as equals, so alternative brick subdivisions with equal displayed content also have equal hash codes.[ref]Java 8 Object API documentation. hashCode(), equal objects must produce equal hash codes
To prove correctness, observe that a maximal run starts whenever occupancy begins or the colour changes, and ends exactly where that occupancy or colour ceases. Those boundaries are determined by the occupied colour at every coordinate. Thus equal occupied colours give the same runs, and equal runs give equal occupied colours. If rows contain and bricks, generating and comparing their runs has time complexity and additional storage, independent of their widths or the magnitude of their coordinates. This meets the requirement to improve on checking every possible cell:
New to topics? Read the docs here!