|                                                                            | 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 | """ Advent of Code
December 3, puzzle B
"""
import re
def main(lines):
	""" Find the one claim that DOESN'T overlap in an NxN square.
		Given a list of claims in the format
		  #123 @ 4,5: 6x7
		where the first number is the claim number, the second number
		group is the x, y coordinates of the upper left corner, and
		the third number group is the x, y size of the rectanglular claim,
		find the number of cells in the square that have more than one
		claim attached to them.
		So: Generate a 1000x1000 table, one value for each cell.
		For each claim:
		  * If the cell is unoccupied, mark with "c"
		  * If the cell is occupied, mark with "X"
		Then cycle through the claims AGAIN. For each claim:
		  * If any of its cells are marked "X", continue.
		  * If ALL its cells are marked "c", that's my claim; report it!
	"""
	#                       grp 1      grp 2    grp 3     grp 4    grp 5
	pattern = re.compile("#([0-9]+) @ ([0-9]+),([0-9]+): ([0-9]+)x([0-9]+)")
	# Generate a 1000x1000 list of empty ("") cells using list comprehensions
	fabric = [["" for y in range(1000)] for x in range(1000)] # fabric[y][x] (it's backwards!)
	# first cycle, to mark claims
	for line in lines:
		m = pattern.match(line)
		claim = int(m.group(1))
		# because xleft and ytop are "distance from the edge", they're zero-indexed
		xleft, ytop, xwidth, yheight = int(m.group(2)), int(m.group(3)), int(m.group(4)), int(m.group(5))
		xright = xleft + xwidth
		ybottom = ytop + yheight
		for j in range(ytop, ybottom): # ranges include the first value but not the second
			for i in range(xleft, xright):
				if fabric[j][i] == "": # if the cell is unclaimed
					fabric[j][i] = "c" # claim it
				else:                  # otherwise
					fabric[j][i] = "X" # mark it X so we know it's contested
	# second cycle, to check claims
	for line in lines:
		m = pattern.match(line)
		claim = int(m.group(1))
		xleft, ytop, xwidth, yheight = int(m.group(2)), int(m.group(3)), int(m.group(4)), int(m.group(5))
		xright = xleft + xwidth
		ybottom = ytop + yheight
		contested = False
		for j in range(ytop, ybottom): # ranges include the first value but not the second
			for i in range(xleft, xright):
				if fabric[j][i] == "X": # if the cell is contested
					contested = True    # oh well
					break			    # break out
										# otherwise continue
		if contested == False:
			print("Claim {} does not overlap!".format(claim))
			return
# (I don't need isX anymore.)
if __name__ == "__main__":
	lines = []
	with open("03in.txt","r") as f:
		for line in f:
			lines.append(line.strip())
	main(lines)
 |