summaryrefslogtreecommitdiff
path: root/2024/day15/solve2.py
diff options
context:
space:
mode:
authorBotond Hende <nettingman@gmail.com>2024-12-15 18:48:54 +0100
committerBotond Hende <nettingman@gmail.com>2024-12-15 18:48:54 +0100
commit566032d375e65abb17e417faf7f9c1f64de2eaba (patch)
treecba14cd03e0ca63d471d8e9d1045c3ce64d8372f /2024/day15/solve2.py
parent83c2415177293e6b67e7208ca95a2f01e30fb344 (diff)
2024 day15
Diffstat (limited to '2024/day15/solve2.py')
-rw-r--r--2024/day15/solve2.py119
1 files changed, 119 insertions, 0 deletions
diff --git a/2024/day15/solve2.py b/2024/day15/solve2.py
new file mode 100644
index 0000000..86e5c82
--- /dev/null
+++ b/2024/day15/solve2.py
@@ -0,0 +1,119 @@
+def get_affected_boxes_if_can_move(data: list[list[str]], current_pos: tuple[int, int],
+ affected_box_positions: list[tuple[int, int]], direction: tuple[int, int]) -> bool:
+ current_char = data[current_pos[0]][current_pos[1]]
+ if current_char == "]":
+ current_pos = (current_pos[0], current_pos[1] - 1)
+
+ if current_char in affected_box_positions:
+ return True
+
+ if current_char != "@":
+ affected_box_positions.append(current_pos)
+
+ pushed_positions = []
+ if current_char == "@":
+ pushed_positions.append(direction)
+ elif direction == (0, 1):
+ pushed_positions.append((0, 2))
+ elif direction == (0, -1):
+ pushed_positions.append(direction)
+ else:
+ pushed_positions.append(direction)
+ pushed_positions.append((direction[0], 1))
+
+ for pushed in pushed_positions:
+ pushed_pos = (current_pos[0] + pushed[0], current_pos[1] + pushed[1])
+ pushed_char = data[pushed_pos[0]][pushed_pos[1]]
+ if pushed_char == "#":
+ return False
+ elif pushed_char == "[" or pushed_char == "]":
+ success = get_affected_boxes_if_can_move(data, pushed_pos, affected_box_positions, direction)
+ if not success:
+ return False
+
+ return True
+
+
+def move(data: list[list[str]], current_pos: tuple[int, int],
+ current_order: str, movement_dict: dict[str, tuple[int, int]]) -> tuple[int, int]:
+ assert data[current_pos[0]][current_pos[1]] == "@"
+
+ direction = movement_dict[current_order]
+ can_move = True
+ steps = 0
+ affected_box_positions = []
+ success = get_affected_boxes_if_can_move(data, current_pos, affected_box_positions, direction)
+ if not success:
+ return current_pos
+
+ data[current_pos[0]][current_pos[1]] = "."
+ for box_pos in affected_box_positions:
+ data[box_pos[0]][box_pos[1]] = "."
+ data[box_pos[0]][box_pos[1] + 1] = "."
+
+ current_pos = (current_pos[0] + direction[0], current_pos[1] + direction[1])
+ data[current_pos[0]][current_pos[1]] = "@"
+
+ for box_pos in affected_box_positions:
+ data[box_pos[0] + direction[0]][box_pos[1] + direction[1]] = "["
+ data[box_pos[0] + direction[0]][box_pos[1] + direction[1] + 1] = "]"
+
+ return current_pos
+
+def calculate_gps_data(data: list[list[str]]):
+ result = 0
+ max_cols = len(data[0])
+ for row_pos, row in enumerate(data):
+ for col_pos, char in enumerate(row):
+ if char == "[":
+ result += row_pos * 100 + col_pos
+ return result
+
+movement_dirs = { "<": (0, -1), "v": (1, 0), "^": (-1, 0), ">": (0, 1) }
+map_data = []
+movement_data = ""
+
+with open("input") as f:
+ reading_movement = False
+ for line in f:
+ line = line.strip()
+ if reading_movement:
+ movement_data += line
+ else:
+ if line == "":
+ reading_movement = True
+ else:
+ new_line = []
+ map_data.append(new_line)
+ for char in line:
+ if char == ".":
+ new_line.append(".")
+ new_line.append(".")
+ elif char == "#":
+ new_line.append("#")
+ new_line.append("#")
+ elif char == "O":
+ new_line.append("[")
+ new_line.append("]")
+ else:
+ new_line.append(char)
+ new_line.append(".")
+
+for row_idx, row in enumerate(map_data):
+ for col_idx, char in enumerate(row):
+ if char == "@":
+ robot_row = row_idx
+ robot_col = col_idx
+ break
+ else:
+ continue
+ break
+
+new_pos = (robot_row, robot_col)
+for order in movement_data:
+ new_pos = move(map_data,new_pos, order, movement_dirs)
+
+for line in map_data:
+ print("".join(line))
+
+print(calculate_gps_data(map_data)) \ No newline at end of file