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
2 years ago
|
#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)
|