diff --git a/day17.py b/day17.py new file mode 100644 index 0000000..23f1902 --- /dev/null +++ b/day17.py @@ -0,0 +1,140 @@ +from tools.aoc import AOCDay +from typing import Any + + +ROCK_SHAPES = [ + ["####"], + [' # ', '###', ' # '], + [' #', ' #', '###'], + ['#', '#', '#', '#'], + ['##', '##'] +] + + +class Chamber(list): + def hash(self): + max_len = min(30, len(self) - 1) + return "".join(self[i] for i in range(max_len)) + + +def collide_hor(chamber: list, rock_shape:list, rock_x: int, rock_y: int) -> bool: + if rock_x < 0 or rock_x > 7 - len(rock_shape[0]): + return True + + for i, line in enumerate(rock_shape): + for x, c in enumerate(rock_shape[i]): + if c == ' ': + continue + y = rock_y - ((len(rock_shape) - 1) - i) + if y < 0: + continue + if chamber[y][rock_x + x] == '#': + return True + + return False + + +def settles(chamber: list, rock_shape: list, rock_x: int, rock_y: int) -> bool: + for i, c in enumerate(rock_shape[-1]): + if c == ' ': + continue + if rock_y >= -1 and chamber[rock_y + 1][i + rock_x] == '#': + return True + + if rock_shape[-1] == ' # ': + for i, c in enumerate(rock_shape[-2]): + if c == ' ': + continue + if rock_y > -1 and chamber[rock_y][i + rock_x] == '#': + return True + + return False + + +def drop_rock(chamber: list, rock_shape: list, jet: list, jet_index: int) -> int: + jet_len = len(jet) + rock_index_x = 2 + for i in range(4): + rock_index_x += jet[(jet_index + i) % jet_len] + if not (0 <= rock_index_x <= 7 - len(rock_shape[0])): + rock_index_x = 0 if rock_index_x < 0 else 7 - len(rock_shape[0]) + jet_index = (jet_index + 4) % jet_len + rock_index_y = -1 + while not settles(chamber, rock_shape, rock_index_x, rock_index_y): + rock_index_y += 1 + if not collide_hor(chamber, rock_shape, rock_index_x + jet[jet_index], rock_index_y): + rock_index_x += jet[jet_index] + jet_index = (jet_index + 1) % jet_len + + for i in range(len(rock_shape) - 1, -1, -1): + y = rock_index_y + i - len(rock_shape) + 1 + if y < 0: + chamber.insert(0, ' ') + y = 0 + left = chamber[y][:rock_index_x] + middle = "".join( + "#" if rock_shape[i][x] == '#' or chamber[y][rock_index_x + x] == '#' else ' ' + for x in range(len(rock_shape[i])) + ) + right = chamber[y][rock_index_x + len(rock_shape[i]):] + chamber[y] = left + middle + right + + return jet_index + + +class Day(AOCDay): + inputs = [ + [ + (3068, "input17_test"), + (3059, "input17"), + ], + [ + (1514285714288, "input17_test"), + (1500874635587, "input17"), + ] + ] + + def get_jet_pattern(self) -> list: + return [-1 if x == '<' else 1 for x in self.getInput()] + + def part1(self) -> Any: + chamber = ['#######'] + jet = self.get_jet_pattern() + jet_index = 0 + for rock_fall in range(2022): + jet_index = drop_rock(chamber, ROCK_SHAPES[rock_fall % 5], jet, jet_index) + + return len(chamber) - 1 + + def part2(self) -> Any: + chamber = Chamber(['#######']) + jet = self.get_jet_pattern() + jet_index = drop_rock(chamber, ROCK_SHAPES[0], jet, 0) + rock_index = 1 + cycle = 1 + cycle_cache = {} + while (jet_index, rock_index, chamber.hash()) not in cycle_cache: + cycle_cache[(jet_index, rock_index, chamber.hash())] = (cycle, len(chamber) - 1) + jet_index = drop_rock(chamber, ROCK_SHAPES[rock_index], jet, jet_index) + rock_index = (rock_index + 1) % 5 + cycle += 1 + + cycle_start, cycle_start_len = cycle_cache[(jet_index, rock_index, chamber.hash())] + cycle_height = len(chamber) - 1 - cycle_start_len + cycle_len = cycle - cycle_start + + chamber = Chamber(['#######']) + jet_index = 0 + rock_index = 0 + bottom_part = 1_000_000_000_000 % cycle_len + for _ in range(cycle_len + bottom_part): + jet_index = drop_rock(chamber, ROCK_SHAPES[rock_index % 5], jet, jet_index) + rock_index += 1 + cur_len = len(chamber) - 1 - cycle_height + + return (1_000_000_000_000 // cycle_len * cycle_height) + cur_len + + +if __name__ == '__main__': + day = Day(2022, 17) + day.run(verbose=True) diff --git a/inputs/input17 b/inputs/input17 new file mode 100644 index 0000000..b2f8a7a --- /dev/null +++ b/inputs/input17 @@ -0,0 +1 @@ +>><<<>>>><<<><>>><><<<<>>>><>>>><<<<>><<<<>>>><<<<>>>><<<>>>><<<>><<<<>>><<<<><><<>>><>>>><<<>>><<><<<><<<>>><<>>><<<><<><<>><<>><<<>>>><<<<><<>>>><>><<<>><<>>><<<>>>><<<<>>><<>>><><<<>>><<>>>><>>><<<<>>>><<>><<<<><<<<>><<<<>>><<>>><<<<><>>>><<<><<<<>><>>><<<<><<>>><>><<><><<>>><<<>>><<<<><<>>><><<<>><><<<<>><><<<>><<<>><>><>><<><<<<>>>><<<<>>><><<<><<>>>><<><<>><<>><><<<>>><>><<<>><<<><<><><<>>><<>>>><<<<>>>><<><<>><<<><<>><<<<><>>><>><<>>>><<<<>>><<<>>><<<>>><>>><>>><<<<>>><<<<><<<<>>>><>><<><<>><<<><><>>>><>>>><<<><<<><<<><<>><<<>>><<<>>><<<>>>><<>>><<<>><<<>>><<<<><<<><<>><<<><<>>><<<<>><<<><<<>><<<>><<>>>><<>><>><<<><<<<>>>><><<>><<>>><<><<>>><<>>>><<>>><<><<<<>>><<<>>><><<<>><<><<<><>>>><<>>><<<<>>>><<>>><<<<><<<<>>><<<<>><<><<<<><<><<<><<<<><><<>>>><<>>>><>>><<>>>><<<<>><><<<>>>><<>>><<<>>>><<>><<>><<<<>>><<<>><<>><<<<>>><>>>><<<>>>><<<>><<<<>><<>>><<<>>><<>><<<><<<>>>><<>>><>><<>>>><<>>><>><>><<<<>><<<<>>>><<>><<<>><<<>>><<<>><<>>><<>>>><<>><<>><<><<<<><<<>>>><>><>><<<<>><>><<>>>><<<>><>>><<>><>><>>>><<<<>>><<<>>><>><<<<>>><<<<>>><><<<><<<><<<>>>><<<<><>>>><<><<<>>>><<>>>><>><>>><<<>>>><<<>>>><>>><<<<>>><<<><>>><>>>><<<>><><<<<>>><<<<>><<<><<<<><<<>>><<<<>>><<<<>><<<><>>><<<><<>><<<<>><<<<>>><<>>><<<>>><<<<>>><>><<<>>>><<<<>><<<>><>>><<<>>>><>>>><<><<<>>>><>>>><<<<>>><<<<><<<><<<>>>><<<>><<<<>>>><<<<>>>><<<<><<<>><>>><><<<<>><<<<>>>><<>><<>><<>><<<>>>><<>><<<<><<<<>><>><<<<>>><<<>>><<<>>><<<<><<>><<<<><<>>><<<>>><<<>><><>><<>><<<<>>><<<<>>>><<<>><>>>><<<<><>>>><>>><<<<>><<>>>><<<<>>><<<>>>><>>><<<><<><<<>><>>>><<<>><<<<>>><>>><<<>><>><<<>>>><<<<>>>><<>><<<>>><<<<>>><<<<><>><<<>><<<>><<<>>><>>><<<>><<<<>>><<<<>>><<<<>>><<<<>><<<<>><<<<>>><<<<>>>><<<>><<<>>><<>>>><<>><<<>>>><<<>><<>>>><<<>><<<<>>><<<<><<>>><>><>>>><<>>>><<<<><<<><<><<<><<<<>><><<<><<<>><<<><<>><<<<>>><<<>><<>>>><><<<><><>><>><<<<>><<><>><<<>>><<<>>>><<<><<<>><<>><<>>>><<<<><<>><>><<<>>>><<><<<>>><>>>><<<<>>>><<>>><<>>><<<>>>><<<>>>><<>><<<>>>><<<<>><<<>><<<<>><>><<>><<<>><<<>><<>>>><<<>><<<>><<<<>><<<<>><<<<>>><<<><<<><<<<>>>><<><<<<><<>><>>><<<<>>><<<<><<<<><<<>>><<<><<<>>>><>>><<>>>><>><><<><<<<>>><<<>>><>><<><<<>><<<<>>>><<>>><<<<>><<<><<<>>><<>>><>>>><<>>><<<<>><><<>><<><<>>>><<><<<<>>><<<>>>><>>><<>>><<>>><<>><<<><<<<>><>>>><>>><<<><<<<>>>><<<<>>><>>>><<<<>>><<<><>><><<<<>>><<>>>><<>>><<<>><<>>>><<<>>>><<>>><<>>>><>>><<<<>>>><<<<>>><><<<<>>>><><<<<>><<>>>><<><<>>>><<<><><>>>><><<<<>><<<<>>><<>><>><<<><<<<>>>><<<>>><<<<><<>>>><<<>>>><<<<>>><<<><<<>><<<>>>><<<<>><>>>><<<>><<<>><>>>><<>>>><><<<>>><<<>>>><><<>>><<<><<<><>>>><<>>><<<>>>><><>><><>>>><><<<<><<>><<<>>><>>><<<<>>>><<<<>>>><<<<>>><<><><<>>><<<<>><>>>><<>>><<<>>><<<<>>><<<<>><>><<<<>>>><<>><<>><<<<>><<<<>>>><>>><<<>>>><<<>><<<<>>>><>>>><<>><>>>><>>><<>>>><<<>>>><<<<>><<<<>>>><<<><<<<>>><>>><<<<>><<<<>><>>><>><<<<><<<>><<<><<>><>>>><<<<>><><<<><>>><<<><<>><<<<>>>><<><<<>>><<>><<<><<><<<<>>><<<<><<<><<<>>><>><<<><<<>>>><>>>><<<>>>><<<<>>>><<<>>><><<>>>><<>>>><><<>>><>>>><<<>>><>>>><<<><<<<>><<<>>><<><<><>>>><<<>>><><<<>>><>><>>><<<<>>><<><<<<>>><<<<>>><<>><<>>><<<><<<<>>><<><<<>>>><<<<>>><<<>><>>><<<>><<<>>><>>>><<>><<<<><<>>>><<>>>><<<><<>>>><><>><>>><>><<>><<<<><<><<>>>><>><<<>>><>>><>>>><<<>>>><<<>><<<>><<>><><<<<><<<<>>>><<>>>><<>><<<>><<>><<<<><<<>><>>>><<>>><<<<>><>>><<<<>><<<<>>><<<<><<<>><<<>>>><<<>>><<<>>>><<<<><<<<>>>><<>><<>>><<<><<<>>>><<>>><>><<>>>><<<>>>><<>>>><>>><>>><<>><<<<><<<<>><<<<>>><<<<>><>><<<>><>>>><><<<<>>>><>><<<>>>><<<><<>>><<><><<<>>><>><<><>>><<<<><<>><<<>><<<>>><<>>><<<>>><<<><<>><>>>><>><<<<>><><>>><>>>><>>><<<>>><<>><<<><>>><>>><<>>>><<<><<<<>>><<<<><<>><<<>>>><<<>>><<<><>>>><><<><<<<>>><<<<>><<<<>><<>>><<>>>><>>>><<<><<<><>>>><>><<>>><<>>>><<<<><>><><<<><<<>>><<<<>><<<><<<><>>><<<>>><>>><<<<>>><><>>>><<<<><<<<>>><<>>><<>>>><<<<>>>><>>><><<>>>><><<<>>><<<>>>><>><<>>><<<>>>><>>>><<<<>>>><>><<<>>>><>><>>>><<><>>><<>>><>>>><<<>>>><<<<><<<<>>><<<<>>>><><>><<><<><<<<>>>><<><<>><<>><<<>><<<<>>>><><><<>><>>>><>>><<>>><<>><<<<>><<>><<<<>>>><>>>><<>>>><<<>>>><<<<>>>><<>>><><<<<>>><<>><>>><<>>>><<<<>>><<<<>>><<>>><<><<<<>>><>>>><<<>>>><<<<><>>>><<<<>><<<<>>>><<>><<<>><<<<>>><<<<>><<<>><>>><<<>>>><>>>><<<><<<>>>><<<>>><<<<><<>>><<<>>><<>><><<<<>>>><<><<<>>><<<>>><<<>>><<<<>><<<<>><<<<>>>><<<><>><<><<<<>>>><<<<>><<<>>>><><<<>>><<<><>>>><<>>>><<<<>>>><<<<>>><<>><<<>>><<><<>>><<<>>>><<<<><<<<>>>><<<>>>><<<>>>><<><<<>>><<<>>><>><<>>><<<><<<>>>><<<>>>><<>>>><<<<>>>><<>>><>>><<<<>>><<<<><<<>>><<<><<<<>>>><><<>>><>>>><<>>>><<<>>><>><<<>>><<<>>><<>>>><<<<><<>><<>>>><<<<>><<>>>><>><<<<>>>><<><<<><>>>><<<<><<<>><<>>>><>><<>><<<<>>>><<<<>><<>>>><<>>><><<<<>><><<<<><<<<>>>><><>><<<<>><<<>>><>><<<><<<>><<<<>>>><>>><<<<>>><<<<><<>>><<<<>>><<<<><<<<>>>><>>>><<<>>>><>>><<>>>><<<<>><<><<<>>><<<>>>><<><<<<>>><>><<>>>><<<<>><><>><<><>><>>><<><<<>><<<<><>>><<<<>>><>>><>>>><>>><<>>>><<<<>>>><<<<>><>><<<<><<<<><<<<>><<<>>>><<<><<<>><>>><>>><<>>><<<<><<><<>>><<<>><<<>>><><<>>>><<<<>>><<<>>>><<>><<<>>>><<<<>>><<<<>>><>>><<<>>><<>><<<>>>><>>>><<>>><>><>><<>><<>>><<<<>>>><><><<>>>><<<>>>><<><<<>>>><>><>>><>>><<>><>>>><>><<>>><<<<>>><<<>>><<<>>>><<><<<>><><<>><>>>><<>>>><<<<>>>><>><><<<<>><<>>>><>><><>>><<<>>><>>>><>><<<<>><>><>><<<>>><><<>><>><<>><<<<>>>><><<>>><<<>>>><><<<><<<<>>>><>>><<>>><<<><<<<>><<<>>>><<<>>><<<>><>><<<<><<<<><<<>>>><<<>>><<><<<>>><<<<>>>><<<>>><><<<>><<<><<>>>><><>>><<<><<<>><<>>>><<<>><<<<><<><<<<>>><<>>><<<<>>>><<<>>>><<<<>>><<<<>><>><<>>><<><<<>>>><<<>><<<<><<>>>><<<<>><<<<>><<>>>><><<<<>><<<<>>><<<<>>>><<>>>><>>>><<>><<>>><<<>><<><<<>>>><<>>>><<<>><<<><<>><<><<<>><<<<><<>>>><>>><<>>>><<<><<>>>><<<>>>><<<>><<<<>>>><<<<>><<<<>><>>><>>>><<>>>><<><<>>><<<<><<>>>><>><<>><>>>><<<<>>><<<<>><<<<>>>><<<<><<<<><<><<><><<>>>><>><>>><<<<>><<>>><>>>><><<<><<>><<<>>>><<<<>><<<<><<>><<<><<>><<<>>><>><<<>><<>>>><<>><><><<<>>>><<<><<<>>>><>><<<>>><<<>>>><<>>>><<<<>>>><>><<<>><<<>>>><<<<>>>><>><<<<><<<>>><<<<>>><<>>><>>>><><>>>><<>>><<<>>>><>><<<<>>>><<>>><<><<><<<<>>>><<<><<<<>>>><<>>>><<<><<>>>><<<<>>>><<<<>>>><<<>>><<<<>>><<<><<<><<<>><<>><>>><<><<><<<<>><<<<>>>><<<<><<>>>><<<>><<<>>><<<>>><<<<><<<<>>><<<<>><<<>><>>><<>>><<<<>>><><<><<<>>><>><>>><<<>>>><<<>>><<<<>>>><<<>>><<<><<<><<<>>>><>>>><<<<>>><<>>><<>>>><<<><<<>>><<<>>>><<<<><<<<>>><<>><>>>><<<<><>><>><<>>><<><<<>>>><<<<>><<<<>><<>>>><<<<>>><<<<><>><<<>>>><<<<>>>><<<>>><<>>><<>>><><>>><><<<<><<<<>><<><><<><<<<>><<<>>>><<>>><<<<>><<<>>><<<<>>>><<<<>>>><<<>><<<><<>>><>>><<<<>><<>>><>><<<<>>><<<<>>>><<>><>>>><<<<>>><>><>><<<>>>><<<>>><<<>><<<<>>>><<<>>><<<>>>><<>><>>><<<<>>><<>><<<><<<>><<<>><<<>><<<<>><<<><<>>><><<<>>>><<<<>>><>>><<>>>><<<><<>>><>>>><><<>><<>><<<<>><<<<>>><<<>>>><>>>><<<><><<<<>><<>>>><<<<>>>><<<>>><<<<>>>><<<>>><<>>><<>>>><<>>><>>>><<<>><<<><>><<<><<><>>><>>>><<<>>><<>>>><<>><>><>>>><<<<>><<>>>><<><<>>><>><<<<><<><<<>>>><<<<>>><>>>><<<>>><<<<><<<>>>><<>>>><<<<>>>><<><<<<><><<>>><<<<>><>><<<>><<><>><<>>>><<<<><<<><<<>>><<<><<>>><<>>>><><<>>>><<>><>>>><<<<>>>><>><<><<<<>>>><<<<>>><<<>><<<>>><<>>><<<<><>>><<><>><<<<><>>>><<<>>><<<<><<><>><<<>>>><<><><><<>><<>>>><<<<>>><<<>>>><<<>><>>>><>>>><<<<>>>><<<<>>>><<<<>>>><<<<>>>><>>>><<>>>><<<>>><<<<>><<<>><<><<>><>>>><<<><<<>>>><<<>>><<<>>>><<<>>>><<<>>>><<<<>><<<<>>><<<>>>><<><<<<><<<<>>>><<<<>><<<<>>>><<<>>><<<<>><<<<>>>><><<<<><<<<><>><<<>><<<><<>><<><<<>><<>><<>>>><<>>><>>><<<<>>><<<<>><<<<>>>><<<>>>><>><>>>><>>>><<>>><<<>><<>>><<<<><<<<>>><<<>>>><<><<>><<<<>><<<><<<>>><><<<<>><<<<>><<<>>>><>>>><<>>><<<<>>><<<<>>><<>>>><<<>>><<<<>>>><<<<>>><<<><><<<>>>><<<>><>>>><<<<>><<><<><<<><<<><>><<>>>><<<><<<<>><>>>><<>>>><>>><<<<>>><<<<>><<>>><<<>>><<<<>><<<<>>>><<<><>>><<<<>><>><<<><<<>>>><>>><<<<>>><<<>><>><>><<<>>>><<>>>><<<><<>>><<<<>>>><<>>><<<>><<<<>>><<>>><<<<><<<<>>>><<>>>><<<<>>>><<<<>>>><<><<<>><<<<>><<<>><<<>><<<<>>><>>><<<><>>>><<<<>>>><<>>>><<<>><<<<><><<<<>>><<<<>>>><<>>><<>>><<<>><<<<>>>><<<<>>>><>><>><<<<>>>><<<>>>><<><<<><<>><<<<>><<<>><<<<>><>>>><<<<>>>><<<<>>>><<<>>>><<<<>>><<>>>><<>>>><><<<>><<<>>><<<><<>>><><<<><>>>><<<<>>><>><>><<>>>><<<<>>>><<<<>>><>><<<<><<>>><>>>><<>><<>>>><<>>><<<<>>><<<>>><>><<<>><<<>>>><<<>><<<>><<>>><>><<<<>>><<<<>><<<><<<>><<<<>>>><<><<<>>><<<<>>><<><<><>>>><<<>>><<<>>>><<<>><<<>><<<<>><<<<>>><<<<>>>><<<>>><<<>><<<<>><<<>>>><><<><<><>><<<>>><<>>><<<<>>>><<<<>>><<<><<>><<<><<<<>><<<<>>><<<<><>>><<<>><<><><<<>>>><<<<><<<>>><<<>>>><<<<>>>><<<>><<<<>>>><<<><<<<>><<>>>><<<>><<>>>><<><<<>>>><><>><<<<>>><><<<>>>><<<><<><<>>><<<<>>><<<>><>><<<><<<>><<<<><<<<>><<<<><<<<>><><><<<><>>><>>><>>>><<<<>>>><<<>>><><>>>><<<<>>><<<>>><<<<>><<<>><<<><<><<><<>>>><><<<>><<><>>><<<<>>><<<<>>><<><<<<>><<<<><<<><<<>>>><<<>><<<>><<<<>><<<<><<<>>>><<<<><<<<>><<<<><<<<>>><<<<>>><>>><<<<>><<>>>><<<>>>><<<<>>><<>><<<<>><>>><>>>><<><<>>>><<>><>>>><>>><>><<>>>><<<<>>>><<<<><<<<><<<>>><<<>><<<<>>><><<<<>><<<<>><><<<<>>><<<<><<><<><<>><<<><>>>><<<<>><>><<>>>><<<>>>><>><>><<>>>><>><><<<>><><>>><<>>><<>><>>><>>>><<<<>><<>>><<>>><>><<<>>>><<<>><<<>>>><<<<>><<<<>>><<<>>>><<<<>>><>>><><<<<>>><>><<<>><<<<><<><<<>><<>>><<><<<<>>><<<>>><<<><>><><<<<>>>><<<><<><>><<>>>><<<>>><<<>>><<<><>><><<>>><<><<>>><><<>>>><>>><<<<>>><<>>><<<<><>><<<><><<<<><<>>><<>>>><<<>>><<<>><<>>>><<<><<<>><<>>>><<>>><<<<>>><<<>>>><<>>>><<<<><<>><<>><<><>>><<><<<<>><<>><<<>><<<<><><<<<>>><>><<<<>>>><<<>>>><<<<>><>>>><>>>><<<<><<>>><<<<>><<<<>><<<>><<<>><><<<<><<><<<><>>>><<<<>>>><>><><>><<<<><<>>>><<><>><<>>><<<<>>>><<<<>>>><>>>><<>>><<<>>>><<>>><<<>>>><<<<>><<<><>>>><<>><<>>><><<>><<<>>>><><<>>>><<<>><<<<>>><><>>><<<><<>>><<<<>><<<>><>><<<>>><<<<>><<<<><<<<>>><<<<>>>><><<<<>><<<<>><<<><<>><<><<<>><<<>><<>>>><>><>><<>>><<><<>>>><>>><<><<<><<>><<>><<><>>>><<>>><<><<<>>>><<<<><<>>>><<><<><<<>>><<><<<>><<<<>><<<<><<>><<<>>><<>>><<<<>>><<>><<<>>>><<<<>>>><>>>><<<<>><<>><<<<>>><<><<<>>>><<<>><<<<>><<<>>>><>><<>>>><<<<>>><<<<>>>><>>>><<<<>><>>>><<<<><<<<>>><<>>><<<<>><<>>>><><<>><<>>><<<>><<<<>><>>><>>>><>>><<<<><>>>><<<>><>>><<<<>><<<>>><<<><<<>>><<<<>>>><<<>>>><>>><<>><<>><<>>><<<<>>>><<<<>>><<<>><<><<<>><>><<<>>>><<<>><<<>><<<>>>><<<><>><<<>>>><<>>>><<>>><<<>>><>>>><<<<><<<<>>>><<>><<<<><<<<>>><<>><<<>><>>><>>>><<<<>>>><<<>><<>>><>>>><<>><<>>><<><<><<>>><<>><<<>>>><<>>>><<<<>>> diff --git a/inputs/input17_test b/inputs/input17_test new file mode 100644 index 0000000..fb5d89e --- /dev/null +++ b/inputs/input17_test @@ -0,0 +1 @@ +>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>> \ No newline at end of file