17.py
1 from lib import * 2 3 input = read_input(2022, 17).strip() 4 5 SHAPES = [ 6 [[1, 1, 1, 1]], 7 [[0, 1, 0], [1, 1, 1], [0, 1, 0]], 8 [[0, 0, 1], [0, 0, 1], [1, 1, 1]], 9 [[1], [1], [1], [1]], 10 [[1, 1], [1, 1]], 11 ] 12 13 WIDTH = 7 14 START_X = 2 15 START_Y = 3 16 17 18 def part1(): 19 grid = set() 20 height = 0 21 sh = 0 22 st = 0 23 24 def test(s, x, y): 25 return ( 26 y - len(s) >= -1 27 and x >= 0 28 and x + len(s[0]) <= WIDTH 29 and all((y - i, x + j) not in grid for i, r in enumerate(s) for j, k in enumerate(r) if k) 30 ) 31 32 def add(s, x, y): 33 grid.update((y - i, x + j) for i, r in enumerate(s) for j, k in enumerate(r) if k) 34 35 for _ in range(2022): 36 s = SHAPES[sh] 37 sh = (sh + 1) % len(SHAPES) 38 x = START_X 39 y = height + START_Y + len(s) - 1 40 while True: 41 d = {"<": -1, ">": 1}[input[st]] 42 st = (st + 1) % len(input) 43 if test(s, x + d, y): 44 x += d 45 if test(s, x, y - 1): 46 y -= 1 47 else: 48 add(s, x, y) 49 height = max(y + 1, height) 50 break 51 return height 52 53 54 def part2(): 55 grid = set() 56 height = 0 57 st = 0 58 sh = 0 59 60 def test(s, x, y): 61 return ( 62 y - len(s) >= -1 63 and x >= 0 64 and x + len(s[0]) <= WIDTH 65 and all((y - i, x + j) not in grid for i, r in enumerate(s) for j, k in enumerate(r) if k) 66 ) 67 68 def add(s, x, y): 69 grid.update((y - i, x + j) for i, r in enumerate(s) for j, k in enumerate(r) if k) 70 71 seen = [] 72 idx = {} 73 heights = [] 74 75 round = 0 76 while True: 77 k = sh, st 78 seen.append(k) 79 heights.append(height) 80 if k in idx: 81 l = len(seen) - idx[k] - 1 82 if seen[-l:] == seen[-2 * l : -l]: 83 break 84 idx[k] = round 85 s = SHAPES[sh] 86 sh = (sh + 1) % len(SHAPES) 87 x = START_X 88 y = height + START_Y + len(s) - 1 89 while True: 90 d = {"<": -1, ">": 1}[input[st]] 91 st = (st + 1) % len(input) 92 if test(s, x + d, y): 93 x += d 94 if test(s, x, y - 1): 95 y -= 1 96 else: 97 add(s, x, y) 98 height = max(y + 1, height) 99 break 100 round += 1 101 102 left = 1000000000000 - round 103 height += left // l * (heights[-1] - heights[-l - 1]) 104 height += heights[-l - 1 + left % l] - heights[-l - 1] 105 return height 106 107 108 print(part1()) 109 print(part2())