You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.9 KiB
133 lines
3.9 KiB
#defining a class for the map |
|
class groveMap(): |
|
def __init__(self): |
|
self.grid = [] |
|
self.checkOrder = [((-1, -1),(-1, 0),(-1, 1)),((1, -1),(1, 0),(1, 1)),((-1, -1),(0, -1),(1, -1)),((-1, 1),(0, 1),(1, 1))] |
|
self.round = 0 |
|
|
|
def addLine(self, line): |
|
self.grid.append(list(line)) |
|
|
|
def makeMove(self, elve, destination): |
|
global lastRound |
|
if destination not in self.doubles and elve != destination: |
|
self.grid[elve[0]][elve[1]] = '.' |
|
self.grid[destination[0]][destination[1]] = '#' |
|
lastRound = False |
|
|
|
def changeOrder(self): |
|
self.checkOrder.append(self.checkOrder[0]) |
|
self.checkOrder.pop(0) |
|
|
|
def findElves(self): |
|
self.round += 1 |
|
self.extendGrid() |
|
elves = {} |
|
self.destList = [] |
|
for y in range(len(self.grid)): |
|
for x in range(len(self.grid[y])): |
|
if self.grid[y][x] == '#': |
|
dest = self.goTo(y, x) |
|
elves[(y, x)] = dest |
|
self.destList.append(dest) |
|
self.findDoubles() |
|
self.changeOrder() |
|
return elves |
|
|
|
def findDoubles(self): |
|
self.doubles = [] |
|
for dest in self.destList: |
|
if self.destList.count(dest) > 1 and dest not in self.doubles: |
|
self.doubles.append(dest) |
|
|
|
def extendGrid(self): |
|
self.grid.append(['.' for _ in range(len(self.grid[0]))]) |
|
self.grid.insert(0, ['.' for _ in range(len(self.grid[-1]))]) |
|
for i in range(len(self.grid)): |
|
self.grid[i].insert(0, '.') |
|
self.grid[i].append('.') |
|
|
|
def goTo(self, y, x): |
|
count = 0 |
|
for directions in reversed(self.checkOrder): |
|
dir1, dir2, dir3 = directions |
|
if self.grid[y + dir1[0]][x + dir1[1]] == '.' and self.grid[y + dir2[0]][x + dir2[1]] == '.' and self.grid[y + dir3[0]][x + dir3[1]] == '.': |
|
count += 1 |
|
destY = y + dir2[0] |
|
destX = x + dir2[1] |
|
if count in [0, 4]: |
|
destY = y |
|
destX = x |
|
return (destY, destX) |
|
|
|
def cleanup(self): |
|
while True: |
|
if '#' in self.grid[0]: |
|
break |
|
self.grid.pop(0) |
|
while True: |
|
if '#' in self.grid[-1]: |
|
break |
|
self.grid.pop(-1) |
|
done = False |
|
while not done: |
|
for y in range(len(self.grid)): |
|
if self.grid[y][0] == '#': |
|
done = True |
|
if done: |
|
continue |
|
for y in range(len(self.grid)): |
|
self.grid[y].pop(0) |
|
done = False |
|
while not done: |
|
for y in range(len(self.grid)): |
|
if self.grid[y][-1] == '#': |
|
done = True |
|
if done: |
|
continue |
|
for y in range(len(self.grid)): |
|
self.grid[y].pop(-1) |
|
|
|
def countSolution(self): |
|
count = 0 |
|
for line in self.grid: |
|
count += line.count('.') |
|
return count |
|
|
|
def testPrint(self): |
|
for line in self.grid: |
|
for point in line: |
|
print(point, end=' ') |
|
print('\n') |
|
|
|
|
|
grove = groveMap() |
|
|
|
#read input |
|
with open('input23.txt', 'r') as f: |
|
inp = f.read().splitlines(keepends=False) |
|
|
|
for line in inp: |
|
grove.addLine(line) |
|
|
|
lastRound = False |
|
|
|
# solves part1, uncomment testprint to display state after 10 rounds |
|
for _ in range(10): |
|
elves = grove.findElves() |
|
for elve in elves: |
|
grove.makeMove(elve, elves[elve]) |
|
#grove.testPrint() |
|
grove.cleanup() |
|
print('Empty tiles after round 10: ', grove.countSolution()) |
|
|
|
#solve part2 |
|
while not lastRound: |
|
lastRound = True |
|
elves = grove.findElves() |
|
for elve in elves: |
|
grove.makeMove(elve, elves[elve]) |
|
if grove.round % 100 == 0: |
|
grove.cleanup() |
|
#print(grove.round) |
|
print('final round: ',grove.round) |