my solutions for advent of code 2022
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.

253 lines
7.6 KiB

#rock grid
class Chamber():
def __init__(self):
self.grid = [['#', '#', '#', '#', '#', '#', '#']]
def addEmpty(self, x):
for i in range(x):
self.grid.append(['.', '.', '.', '.', '.', '.', '.'])
def removeEmpty(self):
self.grid = [i for i in self.grid if i != ['.']*7]
def topEdge(self):
return len(self.grid)
def addRock(self, rock):
for add in rock:
y, x = add
self.grid[y][x] = '#'
def testPrint(self):
for gridLine in reversed(self.grid):
line = ''
for point in gridLine:
line += point
print(line)
#Defining Rock Shapes
def line():
relativeX = 0
relativeY = 0
settled = False
chamber.addEmpty(3)
NY = chamber.topEdge()
NX = 2
chamber.addEmpty(1)
while not settled:
if jetstream[jetPosition] == '<':
if NX != 0 and chamber.grid[NY][NX - 1] == '.':
NX -= 1
relativeX -= 1
else:
if NX != 3 and chamber.grid[NY][NX + 4] == '.':
NX += 1
relativeX += 1
jet()
if chamber.grid[NY - 1][NX:NX+4] == ['.', '.', '.', '.',]:
NY -= 1
relativeY -= 1
else:
settled = True
rock = [(NY, NX), (NY, NX + 1), (NY, NX + 2), (NY, NX + 3)]
chamber.addRock(rock)
chamber.removeEmpty()
rockSequence.append(((relativeY, relativeX), 1, chamber.topEdge() - 1))
def cross():
relativeX = 0
relativeY = 0
settled = False
chamber.addEmpty(3)
NY = chamber.topEdge()
NX = 3
chamber.addEmpty(3)
while not settled:
if jetstream[jetPosition] == '<':
if NX != 1 and all(x == '.' for x in (chamber.grid[NY][NX - 1], chamber.grid[NY + 1][NX - 2], chamber.grid[NY + 2][NX - 1])):
NX -= 1
relativeX -= 1
else:
if NX != 5 and all(x == '.' for x in (chamber.grid[NY][NX + 1], chamber.grid[NY + 1][NX + 2], chamber.grid[NY + 2][NX + 1])):
NX += 1
relativeX += 1
jet()
if all(x == '.' for x in (chamber.grid[NY - 1][NX], chamber.grid[NY][NX - 1], chamber.grid[NY][NX + 1])):
NY -= 1
relativeY -= 1
else:
settled = True
rock = [(NY, NX), (NY + 1, NX - 1), (NY + 1, NX), (NY + 1, NX + 1), (NY + 2, NX)]
chamber.addRock(rock)
chamber.removeEmpty()
rockSequence.append(((relativeY, relativeX), 2, chamber.topEdge() - 1))
def l():
relativeX = 0
relativeY = 0
settled = False
chamber.addEmpty(3)
NY = chamber.topEdge()
NX = 2
chamber.addEmpty(3)
while not settled:
if jetstream[jetPosition] == '<':
if NX != 0 and all(x == '.' for x in (chamber.grid[NY][NX - 1], chamber.grid[NY + 1][NX + 1], chamber.grid[NY + 2][NX + 1])):
NX -= 1
relativeX -= 1
else:
if NX != 4 and all(x == '.' for x in (chamber.grid[NY][NX + 3], chamber.grid[NY + 1][NX + 3], chamber.grid[NY + 2][NX + 3])):
NX += 1
relativeX += 1
jet()
if chamber.grid[NY - 1][NX:NX+3] == ['.', '.', '.']:
NY -= 1
relativeY -= 1
else:
settled = True
rock = [(NY, NX), (NY, NX + 1), (NY, NX + 2), (NY + 1, NX + 2), (NY + 2, NX + 2)]
chamber.addRock(rock)
chamber.removeEmpty()
rockSequence.append(((relativeY, relativeX), 3, chamber.topEdge() - 1))
def staff():
relativeX = 0
relativeY = 0
settled = False
chamber.addEmpty(3)
NY = chamber.topEdge()
NX = 2
chamber.addEmpty(4)
while not settled:
if jetstream[jetPosition] == '<':
if NX != 0 and all(x == '.' for x in (chamber.grid[NY][NX - 1], chamber.grid[NY + 1][NX - 1], chamber.grid[NY + 2][NX - 1], chamber.grid[NY + 3][NX - 1])):
NX -= 1
relativeX -= 1
else:
if NX != 6 and all(x == '.' for x in (chamber.grid[NY][NX + 1], chamber.grid[NY + 1][NX + 1], chamber.grid[NY + 2][NX + 1], chamber.grid[NY + 3][NX + 1])):
NX += 1
relativeX += 1
jet()
if chamber.grid[NY -1][NX] == '.':
NY -= 1
relativeY -= 1
else:
settled = True
rock = [(NY, NX), (NY + 1, NX), (NY + 2, NX), (NY + 3, NX)]
chamber.addRock(rock)
chamber.removeEmpty()
rockSequence.append(((relativeY, relativeX), 4, chamber.topEdge() - 1))
def square():
relativeX = 0
relativeY = 0
settled = False
chamber.addEmpty(3)
NY = chamber.topEdge()
NX = 2
chamber.addEmpty(2)
while not settled:
if jetstream[jetPosition] == '<':
if NX != 0 and (chamber.grid[NY][NX -1] == '.' and chamber.grid[NY + 1][NX -1] == '.'):
NX -= 1
relativeX -= 1
else:
if NX != 5 and (chamber.grid[NY][NX + 2] == '.' and chamber.grid[NY + 1][NX + 2] == '.'):
NX += 1
relativeX += 1
jet()
if chamber.grid[NY - 1][NX] == '.' and chamber.grid[NY - 1][NX + 1] == '.':
NY -= 1
relativeY -= 1
else:
settled = True
rock = [(NY, NX), (NY + 1, NX), (NY + 1, NX + 1), (NY, NX + 1)]
chamber.addRock(rock)
chamber.removeEmpty()
rockSequence.append(((relativeY, relativeX), 5, chamber.topEdge() - 1))
#miscelanious
def jet():
global jetPosition
jetPosition += 1
if jetPosition == jetWrap:
jetPosition = 0
def _counter():
global counter
counter += 1
if counter == end:
return True
return False
def cycleFinder():
global cycleFound
global counter
global skippedValue
if cycleFound:
return
position1, _, _ = rockSequence[-1]
position2, _, _ = rockSequence[-2]
position3, _, _ = rockSequence[-3]
position4, _, _ = rockSequence[-4]
position5, _, _ = rockSequence[-5]
position6, _, _ = rockSequence[-6]
position7, _, _ = rockSequence[-7]
cycle[(position1, position2, position3, position4, position5, position6, position7)] = cycle.get((position1, position2, position3, position4, position5, position6, position7), 0) + len(rockSequence)
if cycle[(position1, position2, position3, position4, position5, position6, position7)] > len(rockSequence):
endOfCycle = rockSequence[-5]
index = cycle[(position1, position2, position3, position4, position5, position6, position7)] - len(rockSequence)
startOfCycle = rockSequence[index - 5]
cycleFound = True
cycleLength = len(rockSequence) - index
cycleValue = endOfCycle[2] - startOfCycle[2]
print('found cycle')
n, rest = divmod(end - len(rockSequence), cycleLength)
counter = len(rockSequence) + cycleLength * n
skippedValue = cycleValue * n
#Building Input, defioning variables
with open('input17.txt','r') as f:
inp = f.read().splitlines(keepends=False)
jetstream = list(inp[0])
jetWrap = len(jetstream)
chamber = Chamber()
jetPosition = 0
counter = 0
end = 1000000000000
rockSequence = []
cycle = {}
cycleFound = False
# Main function
while True:
line()
if _counter():
break
cross()
if _counter():
break
l()
if _counter():
break
staff()
if _counter():
break
square()
if _counter():
break
if counter == 5:
pass
else:
cycleFinder()
if counter % 10000 == 0:
print(counter, 'of', end)
print(chamber.topEdge() - 1 + skippedValue)