# Advent of Code: Day 6

Source

Part 1: Given a 1000 by 1000 grid of lights and a list of instructions of the form (turn on|turn off|toggle) 5,10 through 15,20, determine how many lights are on.

lights = [
[False for y in range(1000)]
for x in range(1000)
]

for line in sys.stdin:
mode, x1, y1, x2, y2 = re.match('(.*) (\d+),(\d+) through (\d+),(\d+)', line.strip()).groups()
x1, y1, x2, y2 = map(int, (x1, y1, x2, y2))

for x in range(x1, x2 + 1):
for y in range(y1, y2 + 1):
if mode == 'turn on':
lights[x][y] = True
elif mode == 'turn off':
lights[x][y] = False
else:
lights[x][y] = not lights[x][y]

print(sum(
1 if lights[x][y] else 0
for x in range(1000)
for y in range(1000)
))

At first, I was going to use pyparsing to parse the input, but then I decided that it was far too heavy weight for what I was doing. All I needed was regular expressions. After that, it’s just a matter of creating a relatively large two dimensional array and running each instruction.

This one I actually did twice. I was curious if CPU would be significantly faster than memory (it is) to the extent that it would be faster to just calculate each light as we went:

filters = []
for line in sys.stdin:
m = re.match('(.*) (\d+),(\d+) through (\d+),(\d+)', line.strip())
filters.append([m.group(1)] + list(map(int, m.groups()[1:])))

def is_on(x, y):
on = False
for mode, x1, y1, x2, y2 in filters:
if x1 <= x <= x2 and y1 <= y <= y2:
if mode == 'turn on':
on = True
elif mode == 'turn off':
on = False
else:
on = not on
return on

print(sum(
1 if is_on(x, y) else 0
for x in range(1000)
for y in range(1000)
))

I works at least, giving the same answer, but it’s roughly an order of magnitude slower. So it goes.

Part 2: This time turn on is +1, turn off is -1, toggle is +2 and you cannot go below zero for any single cell.

The code doesn’t actually change much from the first solution to the first part, we just initialize to 0 instead of False and tweak the updates. The only interesting one is the turn off case:

elif mode == 'turn off':
if lights[x][y] > 0:
lights[x][y] -= 1

Since this is the only case that can be negative, it’s the only one we have to special case.