diff --git a/2022/day17.py b/2022/day17.py new file mode 100644 index 0000000..d318d97 --- /dev/null +++ b/2022/day17.py @@ -0,0 +1,124 @@ +from helpers import * + +gas_cycles = read_day(17) +sample_gas_cycles = '>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>' + +rocks = ''' +#### + +.#. +### +.#. + +..# +..# +### + +# +# +# +# + +## +## +'''.strip().split('\n\n') +# rock_shapes = [np.array([[1 if c=='#' else 0 for c in line] for line in r.split('\n')], dtype=np.int8).T for r in rocks] +rock_shapes = [np.fliplr(np.array([[1 if c=='#' else 0 for c in line] for line in r.split('\n')], dtype=np.int8).T) for r in rocks] + +def simulate_rockfall(gas_cycle: str, num_rocks=50000, debug=False) -> ArrayLike: # returns height increment per rock + def p(message): + if debug: + print(message) + + width = 7 + height_5_rocks = 1+3+3+4+2 + max_possible_height = (num_rocks//5 + 2) * height_5_rocks + len_gas_cycle = len(gas_cycle) + + field = np.zeros((7, max_possible_height), dtype=np.int8) + height_increments = np.zeros(num_rocks, dtype=np.int8) + highest = 0 + t = -1 + for r in range(num_rocks): + rock_shape = rock_shapes[r%5] + r_width, r_height = rock_shape.shape + + def check_collision(r_x, r_y): + r_x2 = r_x + r_width + r_y2 = r_y + r_height + if r_x < 0: + p(f'would hit left wall - {r_x, r_x2} at y={r_y}') + return True + if r_x2 > width: + p(f'would hit right wall - {r_x, r_x2} at y={r_y}') + return True + if r_y < 0: + p(f'would hit floor - {r_x, r_x2} at y={r_y}') + return True + return np.any(field[r_x:r_x2, r_y:r_y2] & rock_shape == 1) + + # Spawn rock with bottom-left corner at x=2, y=highest+3 (y-up) + r_x = 2 + r_y = highest + 3 + while True: + t += 1 + if gas_cycle[t%len_gas_cycle] == '>': + if not check_collision(r_x+1, r_y): # move right + r_x += 1 + p('moved right') + else: + if not check_collision(r_x-1, r_y): # move left + r_x -= 1 + p('moved left') + # move down + if check_collision(r_x, r_y-1): + field[r_x:r_x+r_width, r_y:r_y+r_height] |= rock_shape + old_highest = highest + highest = max(highest, r_y+r_height) + height_increments[r] = highest - old_highest + break + else: + r_y -= 1 + p('moved down') + p(f'rock #{r} landed, highest point {highest}, gas cycle {t}, rock shape ({r_width}x{r_height}) at {r_x},{r_y}') + return height_increments + +sample_incs = simulate_rockfall(sample_gas_cycles, 10000) +incs = simulate_rockfall(gas_cycles, 30000) +print(f'Part 1 (sample): {sample_incs[:2022].sum()}') +print(f'Part 1: {incs[:2022].sum()}') + + +def find_cycle_and_infer(increments: ArrayLike, search_cycle_length: int, target_index: int): + search_term = increments[search_cycle_length:search_cycle_length*2] + hits = [] + for st in range(search_cycle_length*2, len(increments)-search_cycle_length): + if np.all(increments[st:st+search_cycle_length] == search_term): + hits.append(st) + print(f'Found loop starting at {st}') + if len(hits) > 2: + break + else: + print('no loop found!') + return + + loop_len = hits[1]-hits[0] + loop_len2 = hits[2]-hits[1] + if loop_len2 == loop_len: + print(f'Confirmed loop of length {loop_len}') + else: + print(f'Mismatched loop lengths of {loop_len} and {loop_len2}!') + return + + base_value = increments[:hits[0]].sum() + loop_values = increments[hits[0]:hits[1]].cumsum() + loop_total = loop_values[-1] + + loops, remainder = divmod(target_index - hits[0], loop_len) + value = base_value + loop_total*loops + if remainder > 0: + value += loop_values[remainder-1] + return value + +print(f'Part 2 (sample): {find_cycle_and_infer(sample_incs, 1000, 1000000000000)}') +print(f'Part 2: {find_cycle_and_infer(incs, 5000, 1000000000000)}') diff --git a/2022/input/17 b/2022/input/17 new file mode 100644 index 0000000..bc6acad --- /dev/null +++ b/2022/input/17 @@ -0,0 +1 @@ +><><<<><<<<>>>><<<><>>><><<<<><<<>><<>>>><<<>>>><<<>><>>>><<<>>><<<>><<>><<<<>><<>>>><<<<><<><<<<>>><<<<>><<>>>><<<<>>><>><<<<>>><>>><<<<>>>><<<<>>><<<<>>>><<<<>><<>>>><<><<<>><>>><<>>>><<<<>>>><<<<>><>>><<<>>><<<>><>>>><<<<>><<<>>><<<<>>><<>>>><>>><<<>>>><<<<><<>>>><<>>><<<>>>><<><<<><<<>>><>>>><<<><<<<><<>><>>>><<<>>>><<<<>><<>>><<><>>>><<>><<<<>><<<><<>>>><<><<<>>><<><<<>>><<<>><<><<<>>>><<<<>>><<<<>>><<>><>>><<><<<><<>><>>><>>>><<<<>><<>>><<<>>><><<>>>><<>>><<>><<>><><><>><<<>>>><>><<<>>>><>>><>><<<<>>>><<<<>>><<<<><<<>>>><<<>><<<><<>><<>>><<<>>><<<>>>><<<>><<<<><<><<<<>>>><<>>><<<>>>><<<<>>>><<<>>>><<>><><<<<>>><<><<>>><<><<<<>>><<<>><<<<><<>>>><<<<>>><>><<<>><<>>>><<<>>><<>>>><>>><<<>><<>><<><<><<<><<<>>>><<<<>>><<<>><><>><<<<>><<<<>>><<<>>><>>><<><<<><<<><>><<<>>><<><><<>>><>><<<<>>>><>>><<>>><><<>><<<<>><>>><>>>><><<>>>><<><><<<>>>><>>>><>>><>>><<<>>>><>>>><>>><<<<>>><<>>>><<><<<<>>><<<><<<<>><<><<<>><<><<><<<>><<<<>>>><>><<<<>>><><<>>><<<>><<>>>><<>><<><<<>>><>><<<>><<<>><>><>>>><<<<>><<<>>><<>><<>>>><>>><<<<>><<<<>><<>><<<<>>><<<<>>><>>><<<<>>>><<>><<<>><>>><<<>>>><<<>>><><<<<>>><<<>>><><<<<>>>><>><<>><<<><<>>>><<<>><<<<>><<<<>>>><<<<>>>><>>><<<>>>><><<<>>>><>>><<<>>>><>>>><<<<><<<>>>><<<>>><>>>><>>>><<<<>>><>>><>>><<><<<<><<<<><<<><<<>>>><<<<>>>><<>>>><<<><<<>><>>>><<>>><<<<><<>>>><>>><><<<<>><<<<>>>><<<<>>>><<<<>><<>><<<<>><<<><>>>><<<>>>><><<><>>>><<<<>><>>><<>>>><<<>>>><<>>><<<<>>>><<<>>>><<>>><<>>><<<<><<>><<<<><<<>>><<<><<<>>>><<><<<<>>>><<<<>>>><<>><>><<>><<>><<<<><<>>>><>><>><<<><>><<<<>><<<<><<<<>>>><<>><<><>>>><<<<><<<>><<<>>>><<<<>>>><>><>>>><<<<>>>><<<>>>><<<><<<<>>>><<>><<<<>>><<<>>><>><<<<>><<>>>><<<<>>>><<>><<>><<<>>><<<<>><<<<><<>><<><<><<<>>>><<>>>><<<<>>>><>>><>>><<<>><><<>>><<>><<<<>>>><<<<>>>><<<<><<><<<>><<<<>><<>>><<<<>>>><<<><<<<>><<<<>>>><<<<>>><<<>>><<<>>>><<<<>>>><<<>>><<><<>>>><<>><<<>>><<<<>><><>>>><<<<><<<>><<><><<>>>><>><<<>>>><<<>>>><<>>>><<<>>><<<<>>>><<<<>>>><<>>>><<>><>>>><>><<<<>><<<<><>><>>><<<<>><<>><><>>>><<<>>>><><>>><>>><><<<<><><>>>><>><<<<><<>><<>><<><<>><<<>>><<>><<<<>>>><><<<>>><><<>><><<<>><<><<<>>>><<>>><<>><<<>><<<>>>><>>>><<>>>><<<><><>>>><<>><>>>><<<>><<<>>>><<<><>>>><<>>>><<<<>><<<<>>><<<>><<<>>>><<<<>>>><<<>>><<<>>>><<>>><<<><<<>>>><<<<>>><<<>>><<<>><><<<>>>><<>>><>>>><><<><<<>>><<<<><>>>><<<<>>>><>>><<>>><<<><<>><><<<<>><>>>><<<<>>>><<<><<>>><<><>><<<<><<<>>>><<<<><<<<>>>><<<<><<<<>>>><<<>><<<>>><<>><<<>>><>>>><<>>>><<<<><<<>>><<<<>>>><<>><<<<><>><>>>><>>><<<><<<><>><<><<<>>><><>>><<<>>>><<<><>><<<>>><>>><>><>><>>>><<<<>>><<<><<<<>>>><<<<>><<>>>><<><<>>>><<>><<>><>>>><>>><<<<><<>><>>>><>><<><<<<>>><<>>>><<<<><><>>><<>><<<>><<>>><>><<<>>><<<<>><>>><<<>>>><<<<>>><<<><<<><<>>>><>>>><<>>><<<<>><><<<>><<<>><>><><<><<<<>><<<>><<<>>>><<>><<<>>>><>>>><<<<>>><<>><<>>><>>><>>><<<<>><<<<><>>>><><<>>><<<<>>>><>>><>><<<<>>>><>>><<<<>>><>>>><<><<<>><<<>>>><<<>>>><>>><<><<<>><<<<>>><<>>>><<>><>>><<><<<>>><>>>><>>><<<<>>>><>>>><>>><><<><<<>><<<<>>><<<<>><<<<><<<>>>><<>>>><>><<><<<<>>>><<>><>>><>>><<<>><<<<>>><><<<>><<<<><<<<>>>><<<><<>><<>><<<<>><<><>>>><>>>><<<>>><<<<>>>><<<<>>>><<<<>><<<>>><<<<>>><>>><<><<<<><<<<>>>><<>>><<<<><>><<>>><<<>>>><><<<<>>><<><>>>><>>><<<><<><<<>>>><<<>><<>>><><<<<><<<><<>><<<<><>>>><>>>><<<>><<<<>>><<>>>><><<><<<<><>>>><<<<>>><>>>><<>><<<>>>><<<<>>><>>><<<><<<>><>>><><<<<>>><<<>>>><<<<>>><>><<>>><<<>><<<<>>><<<><<<<>>><<<>>>><<<<>>><><<>>><<<>>><<><<<<>>><<><<<<>><<>><><<<<>>>><>>><>><<<>>><>>><<<<>>><<<<><<<<><<<<>>>><<<>>><><<<<>>><<<>><<<>>><<><<<>>>><<<<><<>>><<<<>>><<<>>><<<<>>>><<<>>><>>>><<<><>>><><<><>>>><>>>><>><>>>><<>><<>><>>><<>>>><<>>><>><<<>>><<<><<>>><>><<>>>><><<<>>>><<>>>><<>>><<>>><<<>>><<>>>><<<><<<>>>><<>>><<<<><<>>>><<>><<<>><<<<><>>>><<<><<<><><<<<><<<<>>>><<>><><>>><<>><>>>><<<<>>>><>><<>><<<><<<<>><<>>><<<<>>><><<<><<<<>><<<<>><>>>><<<>>>><<<<><<>><<>><<<>>><<><<<>>>><><><<<<>><<>>>><<><<<><><>><<>>><<<<>>><<<<>>>><<<<>><>>>><>>>><<<>>>><>><<>>>><><<<<>>>><><<<<>>><<<<>>><<<<>><>><>><<<><<<<>>><<<><<<>><>>>><<<>>><<<<>>><<><<<<>>><<<>>><<><<>>><<>><<<>><<><<<<><<<<>>><>>>><<<<>><><<<<><<<>>><<<<>>><<<>><<<>>><<<>>><<<>>>><<<<>>>><<<>>><<>>><<<<><<<>><><<><<>>><<<>><<><<>>><<<>>><<>>>><<<<>>>><<<>>><<><<<>>><>><<<><<<<>><<<<>>><<<>>>><<<><<<><<<<>>>><<<<>>>><<>>><<>>>><<>>><<<<>>>><<<<>><<><<>><<<<><>>>><><<<>>><<<>>>><<<<>>><<><>><>>>><<<<>><<<<>><<>>>><<<><<<>>><<>>><<<>>>><<>>><<<>>>><<<<>><<<<>>>><<<<><<<<>>><<<>><<<>>><<>><<>><>>><>>>><<<<><>><<<>><>>>><<<>>>><<><<>><>>>><<<><><>>>><<><<>>>><<>>><>><<<<><<<>>><<>><<<>><<>><<><>>><>><<<<>><<<>><>>><>><<>><<<><<><<>>><<>>><<><<>>><<>>>><>>><<><<<><<>>><<<<>>><<><>>><<<<><><><<<<>>><><>>><>>>><<<><<<>>><<<<>>>><>>>><<>>><>><>><>><<<<>>><<><<><<<><<<>><>><>>><<>>>><<<>><>>>><<<><<<<>><<<<>><<<<>><<>><<<<>>><<<>><<>>><<<<><<>>><><<<><<>>>><<<<>>><<>><<<>>><><<<<>>><<><<<<>>>><>><<<<><>>><<<>>>><><>>><<<><<<><<<<>>>><>>><<<>>>><<>>><>>>><><<<>><<>>>><><<>>>><<<>>>><<<<><<<<><<<>>><<>>><<<<>>><<>>><<>>>><<<>>>><><<<<>>><><<<>>>><>><<><<<<>>>><<<<>>>><><><>><<<>>><<><<<>>>><<>><>>><>>><<<<>>><>><<>>>><<>><<<<><<<>>><<<<><<<>>><<<<><<<>>>><<<<><<>>>><<>><<<<>>><<>><<>><<>>><>>><<<>>><>>>><<<<>>>><<<<><>><<>>>><<<<><<>>>><<<>>>><>>><<>><<<<>><<<><<>>>><<<><<<<><<<<>>>><<<<>><<<><<>>>><>>><<<>>><<<<>><<<<>>><<<><<<>>>><<<>>>><<>><<>>>><<>>>><<<<>>><<>><<<>><<<<><<<><<<>>>><<><><>>>><<>>>><>>><<<<>>><<>><<<>>>><<<>><<<>><<<>><<>><>>><<<>>><<>>>><>><>>><<<>><<<>>>><<<>><<>>>><><><<>>>><<<<><<>><<><<<>><<><>>>><>><<<<>><><<<>><<>><<><<<>><<<>>><<>>>><<><>>>><<<><<>>>><>><<<>>>><<><<>>><>>>><>>>><<>><<>>><<><<<><<<<>><<<><<<<><<<>><<<<>>><<<>><<><<>><<<<><<>>><>>><<<><>><<<>>>><<<<>><<>>>><>>>><<<<>><<<>>>><>>><<>><>>><<<>>>><>>><<<<>>>><>><><<<<>>><<<>><<<>><<<><>>><<<>><<<<>><<><<>><<<<>>><>>>><<<>>>><<>><<<<>><<<<>>><<<<>>>><<><><<<>>>><<><>>><<>><<<<>>>><><<>>><<<<>><<<<><<<>>>><>>>><<>>><<<<>><>><<<<>>><<>>><<<>>>><<<>>><<<<><<<>>><<>><>>><<<<><<><<<>>>><<<>>>><<<><<>><<<<><<>><<<<>>>><>><<<><><<<>>>><<<<>><>><<<<>>><<<<><>>>><<<<>><<>>>><>>>><<<>><<<>>>><>>><<<<>>>><<<>>>><><>>>><<>>><<>>><>>><<>>>><<>>>><<<<>>>><><<<>><<><>>>><<<<>>>><<<<>>><<<<><<><<<><<<>>><<>>>><<>>><>><<<>>><>>><<<<>>>><<>>>><><<<<>><>>><<>><<<<>>><<>>>><<<>><<>>>><<<<>>>><<<<>><>><<>>><>>>><<<<>>>><<<>>>><<>>>><<<<>>>><<<>><>>>><<>>><>>><>><><<>>>><<<<>><<<>>>><<<>>><<<<>>>><>>><<<<><<<><<<<>><>><<>><><<>>><<<>>><<><<>>><<<>><<>>>><>>>><>><<<<>>>><<<>><<>>>><<><<>>>><<<>>>><<<<>><<><<<>><<<>>><<>>>><<>><<>>><<>>><>>>><<<>>>><>>><>>>><<<><<<<><<<>>>><<<>>><<<>><>>><><<<><<<>><<>><<<<>><<><<<>>><>>>><<><<<<>>><>>><<<>>><<<>>>><<<<>>>><>>>><<<<>>>><<<<>>><<>><>><<>><<<>><>><<><<<<><<<<><>><<<>>><<<>><<<>>><<>>><<<<><<<>><<>>>><<>>><<<<>><<<>><<><<>><<>>>><>><><<<>>><<><<<>>>><>>>><>>><>>>><>>>><>>>><>>><<<<>>><<<>><<<<>><<>><<<>>>><<<><><><<><<<<><<<>><><<<<>>>><<<<>>>><>>>><<<<>>><<<>><>>><>><>><<>><<>><<<><<>><<>>><<<>>>><<>>>><>>><<<<>>><>><<<<>>>><<<<>><<>><<><<<<><<>>><<<<>><<<>>><<<>>>><<<<>>><><>>>><<<<>>><><<>>>><<>>>><<<>>><<><<<<>>><<>>><><<<><<<>>>><><<<><<<>><<>>><<<>>><<>>><<>>><>><><<<>>>><<><>><>>><<<>><<<<>>>><>>>><<<<><<<>>><>>>><<<>><<><><<<<>>>><<<<>><>>><>><>>>><<<>><<>>>><<<><><<>>><<<<>>><<<>>><<<<>>>><<>>>><>>>><<>>>><<>>><<<<>><<<<>>><<>><<>><>>>><>>><<<<>>><>>><<<>>><<>>><<><><>><<>><>><>>>><>>>><<>>><>>><<<>>><><<<<><>>><<<<>><>>>><<<<><>>>><<<><<<<>><<<>>>><<<<>>><<<>>>><<<>>><<<<><<<<>>><<<>><>>>><<<>>>><<<><<><<><<>><<<<>><<<>>>><<><<<<>>>><>>><>><<>>>><>>>><>><<<>>><<>>>><<<<>>><>>><<<>>>><<<<>>>><>><>><<<<>>>><<>>><>>>><<<><<>>>><<<>><<>>>><><>>>><>><<<>><><<>>>><<<<>>><<>>><<<<>><<>>>><<<<><<>>><<<>><<>><<<<><<<<><>><<<>><>><<<>>><<>>><<<>>><<>>>><<><<<<><<<>>><<<>>><<<>>><<<>>><<>>><<<<>>>><<<<>>>><<>><<>><<>>><>>><<>>><<<<>>>><<>>>><<<<><>>><<<<>><<>>>><<><>><<<<><<<>><>>><>>><<<<><<<>>>><<>>><<<<>>>><>>>><<<<>>>><<<<><<>>><>><>><<><<<<>><<>><<<>>>><>>><<<>>><<<<><<<>><<<<>>>><<<><><<<>>><<<<><<<<>><<<>>><<<<>>>><<<>>>><>>>><<<>>><<<<><><<<>>><<<>><<<<>>>><<<>>><<<>>>><><<>>>><<<<><<<<>>>><<<>><><<><<<>><<<>>>><>><<>>>><>>>><<<>>>><>><<<>>>><<><<>><<<<>><<>><<<><<<<><>>>><<<><<>><<<<>><<<><>><>>>><<<<>>><<<<>>><><<><<><>><<<<><<<<>>>><<<<><<>>><<><<>><<>>><<>><<<>><<<>>>><<><<>>><<<><>>><<><<<<>>>><<>><<<<>><>><<<<><<>>><<<>>>><<<>><<<<>><<<>>><<<<>>><<<<>>><<>><<>><<<<>>>><<<>>><<<>>><>><<<><>><<<<>>><>>>><<>>><>><>>>><<>>><<<>>>><<<<>>><<>><<<<>><<<>>>><<<>><<<>><<>>>><>>>><<<<>>>><<<<>>><<<>><<>>><<<>><<<<>>><<<>>>><><><<>><>><>>><<>><<<<><<<<>>><<>><<<<>>><<<><<>>><<>>>><<<<>>>><<><<<>>><<<<>>><><>>><<<<>>><<>>><<>><<<>>><>>><<>><<<>>>><<>>><<><>>><<<<>>><>>><<<<>>><>>>><>>>><<<<>><>>><<>><<><<>><>><<>>><>><<<<>>><<<<><<<>>>><<<>><>>><<<<>>><><<<><<>>><<>><<<<>><<<<>><>>><<>>><<<<>>>><>>>><<>>><<<<>>><<<<><<<<>>>><<<<>>><<<><<<<>>><<<>>>><<<><<<<>><<<>>><<<><<<>>><<<><<<>>><<>><<<<>>><>>><<<>>><<>>>><<>>>><>><<<<>>><<>>><<<><<<><<<<>>>><<<><<<<>>>><<<>>>><<<>>>><<>>><<<<>><>>>><<>>><<<>>><>><<>><<<>>><<<<>>><<<>>><<<><<<>>>><<>>><><><>>>><<<<>>><<<<>>><><>><<<<>><<<<>>><<>>>><<>>>><<<><>>>><<<>><<<>>>><<<>>><<>><<>>><<<<><>><<>><>>><<<<><<><<>>>><<<<>>><>>><>>><<<>>>><>><<<><<>><<<>>><<<<>>>><<<>><<>>>><<<>><<<<>>>><>><>>>><<<><<<>><<<>>><<<>>>><><<<<>><<<<>><><>>><>><>>><>><>>><><<<>><<<<>>><>>>><<<>>><<<<><<>>><>>>><<<>>><<<<>>>><<><<<>>><<>>><<<>><<<<>>>><<>>>><<<>>>><>>>><<<>><<<>>><<<<>>>><<<<>>><<<<>><<>><<<><><<<<>>>><>><<<>>>><<>><<>>><<><<<><<<<>>><<>>>><><>>>><>>>><<<><<>>><<<<>>>><>><<<>><<<>>>><<<>>><><<><<<>><<<<>><<<>><>><><<<<>><><>>><<<>>><<<>>>><>>>><<<<>>>><>>><>>><<>>><<>>><>>><>><><<>>>><<><<<>><<<<>>>><<<<>>>><<><<>>><<<<><<><>><<<><<>>><>>>><<><<<<>>>><<>>>><<<<><><><>>><<<>><<<<>><<<>>><<<<>>>><<>><<<<>>>><>><<><<>><<>>>><<<<><<>>>><<>>>><<<<>>><>><>><<>><<<<>><>>>><<<>><<>>>><<<<>><>>>><<<><>>>><<>>>><<<>>>><>>><>>>><<>><<>>><<>>><<<<>>><<<<>>><>>><<<>>>><<<<>>><<<>><<<>>><<<<>>><<<<>>>><<<<>>><<<<><<<>><<><>>>><<<<><<>>><<>><<<>><>><<>>>><<>>>><<<>>>><>>>><<<><<<<>><<<>>><>>><>><>>>><><<>>>><>>>><<<>><<>><<>>><<<>>>><>><<<<>><<<<>>>><>>><<<<>><<>><<<><<>>>><<>>><<<<>>><><<><<<><<<>>><<<>><<>>>><<<><>>><<>>><<<>>><<<<>><<><>