@@ -0,0 +1,72 @@ | |||
""" Advent of Code | |||
December 3, puzzle A | |||
""" | |||
import re | |||
def main(lines): | |||
""" Find the number of overlapped cells 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. | |||
The first task is to find out how big the total square is! | |||
This will also verify that the regular expression works. | |||
Result: This cloth is exactly 1000 inches to a side. | |||
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 iterate through the table and count the number of Xes. | |||
""" | |||
# grp 1 grp 2 grp 3 grp 4 grp 5 | |||
pattern = re.compile("#([0-9]+) @ ([0-9]+),([0-9]+): ([0-9]+)x([0-9]+)") | |||
# maxsize, claim = 0, 0 # only need this for determining cloth size | |||
# 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!) | |||
for line in lines: | |||
m = pattern.match(line) | |||
# 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 | |||
# a helper function, isX, will return 1 if a cell is "X" and 0 if it's not. | |||
contested = sum([sum([isX(cell) for cell in line]) for line in fabric]) | |||
print("There are {} contested cells.".format(contested)) | |||
# Commenting out the "find the size of the cloth" code, but leaving it in for historical purposes | |||
# if xright > maxsize: | |||
# maxsize = xright | |||
# claim = int(m.group(1)) | |||
# if ybottom > maxsize: | |||
# maxsize = ybottom | |||
# claim = int(m.group(1)) | |||
# print("Cloth is {} inches square, thanks to claim {}".format(maxsize, claim)) | |||
def isX(cell): | |||
""" Returns 1 if the cell passed in contains "X", 0 otherwise. | |||
""" | |||
return 1 if cell == "X" else 0 | |||
if __name__ == "__main__": | |||
lines = [] | |||
with open("03in.txt","r") as f: | |||
for line in f: | |||
lines.append(line.strip()) | |||
main(lines) |
@@ -0,0 +1,76 @@ | |||
""" 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) |