# CP Python Logic Confusion on Modern Art (Bronze USACO 2017 US Open p.3)

## Problem Info

USACO 2017 US Open Bronze Problem 3 Modern Art Problem Link

## My Work

``````# Read in grid as 2D array
with open("art.in", 'r') as fin:
grid = [[int(i) for i in fin.readline().strip()] for _ in range(n)]
print(grid)

# Get all possible colors, which is everything visible excluding zero
possible = set()
for row in grid:
for p in row:
if 0 in possible:
possible.remove(0)
print(possible)

# Recursive search function that gets the maximum x of the triangle and maximum y of the triangle, which will be used further down the road to calculate whether or not it is a valid rectangle
def search(grid, i, j, v):
global max_x, max_y, searched, area
if i < 0 or i >= n or j < 0 or j >= n or grid[i][j] != v or (i, j) in searched:
max_x = max(max_x, j)
max_y = max(max_y, i)
return
searched.append((i, j))
area += 1
search(grid, i+1, j, v)
search(grid, i-1, j, v)
search(grid, i, j+1, v)
search(grid, i, j-1, v)

# Use the search, and check if there is a possibility of the rectangle being covered. It it is covered, eliminate the rectangle that covers it from the list of possibilities.
searched = []
for i, row in enumerate(grid):
for j, p in enumerate(row):
if (i, j) in searched or not p:
continue
max_x = 0
max_y = 0
# The area variable is uneeded. Using it for debugging
area = 0
search(grid, i, j, p)
print(area, (max_x-j) * (max_y-i))
print()

for k in range(i, max_y):
for l in range(j, max_x):
if grid[k][l] != p and grid[k][l] in possible:
possible.remove(grid[k][l])

# Write the answer to the output file
with open('art.out', 'w') as fout:
fout.write(str(len(possible)))
``````

## Problem

My logic is pretty clear from the code, and I can get 6 out of 10 test cases, but when I try an input like:

``````4
1234
1234
1234
1334
``````

My program outputs 4 instead of 3, which is the correct answer. Therein lies my problem. I have no idea why it is 3 and not 4

## What I’ve Tried

I’ve read over the problem multiple times, and I still don’t get it.

If anyone could help explain it, that would be great.

### >Solution :

I believe an important part of this problem is to identify "broken" rectangles in the input (i.e rectangles that have overlap). In the case of your last example, `1`, `2`, and `4` are "complete" rectangles, in the sense that they are not explicitly overlapped by any other tiles. `3`, however, is clearly overlapped by `2`, thus, either `2` or `3` existed first, not both. Therefore, there are two complete plus one group of incomplete, giving `3` as the final result. Below is code for a possible solution to this problem:

``````from collections import defaultdict
def w_h(points):
d = {'w':set(), 'h':set()}
for a, b in points:
return [max(b) - min(b) + 1 for b in d.values()]

def original_paintings(p):
d = defaultdict(list)
for x, a in enumerate(p):
for y, s in enumerate(a):
if s:
d[s].append((x, y))
r = {a:(wh:=w_h(b))*wh - len(b) for a, b in d.items()}
return len(r) - len(set(r.values())) + 1

t1 = [[2, 2, 3, 0], [2, 7, 3, 7], [2, 7, 7, 7], [0, 0, 0, 0]]
t2 = [[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 3, 3, 4]]
print(original_paintings(t1))
print(original_paintings(t2))
``````

Output:

``````1
3
``````