#!/usr/bin/env python3 import sys from collections import defaultdict # #### # # .#. # ### # .#. # # ..# # ..# # ### # # # # # # # # # # # ## # ## ROCKS = [[['#','#','#','#']],[['.','#','.'],['#','#','#'],['.','#','.']], [['#','#','#'],['.','.','#'],['.','.','#']],[['#'],['#'],['#'],['#']],[['#','#'],['#','#']]] CHAMBER = defaultdict(lambda: ['.'] * 7) MAX = 0 def show(): for y in range(MAX+1,-1,-1): line = '|' for x in range(0,7): line += CHAMBER[y][x] print(line + '|') print('+-------+') def fall(r, j): rock = ROCKS[r % len(ROCKS)] global MAX x = 2 y = MAX + 3 while True: jet = JETS[j] if jet == '>': # push right if not (x + len(rock[0])) == 7: halt = False for ji in range(len(rock)): for i in range(len(rock[0])): if rock[ji][i] == '#' and CHAMBER[y+ji][x+i+1] == '#': halt = True if not halt: x = x + 1 elif jet == '<': # push left halt = False if not x == 0: for ji in range(len(rock)): for i in range(len(rock[0])): if rock[ji][i] == '#' and CHAMBER[y+ji][x+i-1] == '#': halt = True if not halt: x = x - 1 halt = False for ji in range(len(rock)): for i in range(len(rock[0])): if rock[ji][i] == '#' and CHAMBER[y+ji-1][x+i] == '#': halt = True if y == height or halt: for b in range(y,y+len(rock)): for a in range(x,x+len(rock[0])): CHAMBER[b][a] = rock[b-y][a-x] if CHAMBER[b][a] == '.' else CHAMBER[b][a] if b+1 > MAX: MAX = b+1 break j = (j + 1) % len(JETS) y -= 1 return r+1, (j + 1) % len(JETS) if __name__ == '__main__': global JETS JETS = list(open(sys.argv[1]).read().strip('\n')) global height height = 0 # challenge 1 r, j = 0,0 for i in range(2022): r,j = fall(r,j) res1 = str(MAX) print("challenge 1:" + "\n" + res1 + "\n") # challenge 2 # keep only last 20 values or so, check for cycles for i in range(1000000000000-2022): r,j = fall(r,j) if CHAMBER[MAX-1] == ['#'] * 7 and r == 0: print(i,MAX) res2 = str(height+MAX) print("challenge 2:" + "\n" + res2 + "\n")