Solved 2025 Day 1 Parts 1 & 2
This commit is contained in:
1 parent
4f07ea9f81
commit
1a711cd261
23 files changed
+9528
No files matched your search
@@ -0,0 +1,342 @@
|
||||
ROBOT_SPEED: int = 1
|
||||
|
||||
class Coord:
|
||||
x: int
|
||||
y: int
|
||||
|
||||
def __init__(self, x: int, y: int):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f'({self.x}, {self.y})'
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
return other.x == self.x and other.y == self.y
|
||||
|
||||
def __add__(self, other):
|
||||
return Coord(self.x + other.x, self.y + other.y)
|
||||
|
||||
def __sub__(self, other):
|
||||
return Coord(self.x - other.x, self.y - other.y)
|
||||
|
||||
def __mul__(self, other):
|
||||
return Coord(self.x * other, self.y * other)
|
||||
|
||||
def __rmul__(self, other):
|
||||
return Coord(self.x * other, self.y * other)
|
||||
|
||||
def copy(self):
|
||||
return Coord(self.x, self.y)
|
||||
|
||||
class Warehouse:
|
||||
robot: Coord
|
||||
walls: list[Coord] = []
|
||||
boxes: list[Coord] = []
|
||||
width: int
|
||||
height: int
|
||||
|
||||
def __init__(self, warehouse_map: list[str]):
|
||||
for y, line in enumerate(warehouse_map):
|
||||
for x, c in enumerate(line):
|
||||
match c:
|
||||
case "#":
|
||||
self.walls.append(Coord(x, y))
|
||||
case "@":
|
||||
self.robot = Coord(x, y)
|
||||
case "O":
|
||||
self.boxes.append(Coord(x, y))
|
||||
|
||||
self.width = len(warehouse_map[0])
|
||||
self.height = len(warehouse_map)
|
||||
|
||||
def __str__(self) -> str:
|
||||
w = [['.'] * self.width for _ in range(self.height)]
|
||||
|
||||
for box in self.boxes:
|
||||
w[box.y][box.x] = 'O'
|
||||
|
||||
for wall in self.walls:
|
||||
w[wall.y][wall.x] = '#'
|
||||
|
||||
w[self.robot.y][self.robot.x] = '@'
|
||||
|
||||
s = ''
|
||||
for row in w:
|
||||
for c in row:
|
||||
s += c
|
||||
s += '\n'
|
||||
|
||||
return s
|
||||
|
||||
def move_robot(self, command: str) -> None:
|
||||
|
||||
dx, dy = 0, 0
|
||||
match command:
|
||||
case '>':
|
||||
dx += 1
|
||||
case '<':
|
||||
dx -= 1
|
||||
case 'v':
|
||||
dy += 1
|
||||
case '^':
|
||||
dy -= 1
|
||||
|
||||
movement = Coord(dx, dy)
|
||||
|
||||
new_pos = self.robot + movement
|
||||
|
||||
if new_pos in self.walls:
|
||||
return None
|
||||
|
||||
if new_pos in self.boxes:
|
||||
if self.push_box(new_pos, movement):
|
||||
self.robot = new_pos
|
||||
return None
|
||||
|
||||
self.robot = new_pos
|
||||
|
||||
def push_box(self, box: Coord, movement: Coord) -> bool:
|
||||
new_pos: Coord = box + movement
|
||||
|
||||
if new_pos in self.walls:
|
||||
return False
|
||||
|
||||
if new_pos in self.boxes:
|
||||
if not self.push_box(new_pos, movement):
|
||||
return False
|
||||
|
||||
self.boxes.remove(box)
|
||||
self.boxes.append(new_pos)
|
||||
return True
|
||||
|
||||
def score(self) -> int:
|
||||
total = 0
|
||||
for box in self.boxes:
|
||||
total += 100 * box.y + box.x
|
||||
|
||||
return total
|
||||
|
||||
class BigBox:
|
||||
right: Coord
|
||||
left: Coord
|
||||
|
||||
def __init__(self, left: Coord):
|
||||
self.left = left
|
||||
self.right = Coord(left.x + 1, left.y)
|
||||
|
||||
def __add__(self, other: Coord):
|
||||
return BigBox(self.left + other)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
return self.left == other.left and self.right == other.right
|
||||
|
||||
def __str__(self) -> str:
|
||||
return '[]'
|
||||
|
||||
class SecondWarehouse:
|
||||
robot: Coord
|
||||
walls: list[Coord] = []
|
||||
boxes: list[BigBox] = []
|
||||
width: int
|
||||
height: int
|
||||
|
||||
def __init__(self, warehouse_map: list[str]):
|
||||
for y, line in enumerate(warehouse_map):
|
||||
offset = 0
|
||||
for x, c in enumerate(line):
|
||||
match c:
|
||||
case "#":
|
||||
self.walls.append(Coord(x + offset, y))
|
||||
self.walls.append(Coord(x + 1 + offset, y))
|
||||
case "@":
|
||||
self.robot = Coord(x + offset, y)
|
||||
case "O":
|
||||
self.boxes.append(BigBox(Coord(x + offset, y)))
|
||||
|
||||
offset += 1
|
||||
|
||||
self.width = len(warehouse_map[0]) * 2
|
||||
self.height = len(warehouse_map)
|
||||
|
||||
def __str__(self) -> str:
|
||||
w = [['.'] * self.width for _ in range(self.height)]
|
||||
|
||||
for box in self.boxes:
|
||||
w[box.left.y][box.left.x] = '['
|
||||
w[box.right.y][box.right.x] = ']'
|
||||
|
||||
for wall in self.walls:
|
||||
w[wall.y][wall.x] = '#'
|
||||
|
||||
w[self.robot.y][self.robot.x] = '@'
|
||||
|
||||
s = ''
|
||||
for row in w:
|
||||
for c in row:
|
||||
s += c
|
||||
s += '\n'
|
||||
|
||||
return s
|
||||
|
||||
def move_robot(self, command: str) -> None:
|
||||
|
||||
dx, dy = 0, 0
|
||||
match command:
|
||||
case '>':
|
||||
dx += 1
|
||||
case '<':
|
||||
dx -= 1
|
||||
case 'v':
|
||||
dy += 1
|
||||
case '^':
|
||||
dy -= 1
|
||||
|
||||
movement = Coord(dx, dy)
|
||||
|
||||
new_pos = self.robot + movement
|
||||
|
||||
if new_pos in self.walls:
|
||||
return
|
||||
|
||||
if box := self.is_box(new_pos):
|
||||
if self.push_box(box, movement):
|
||||
self.robot = new_pos
|
||||
return
|
||||
|
||||
self.robot = new_pos
|
||||
|
||||
def is_box(self, pos: Coord) -> BigBox | None:
|
||||
for box in self.boxes:
|
||||
if pos == box.left or pos == box.right:
|
||||
return box
|
||||
|
||||
return None
|
||||
|
||||
def push_box(self, box: BigBox, movement: Coord) -> bool:
|
||||
new_box: BigBox = box + movement
|
||||
|
||||
|
||||
|
||||
|
||||
# def push_box(self, box: Coord, movement: Coord) -> bool:
|
||||
|
||||
# if movement.y != 0:
|
||||
# return self.vertical_push(box, movement)
|
||||
|
||||
# new_pos: Coord = box + movement
|
||||
# new_pos2 = new_pos.copy()
|
||||
# if movement.x > 0:
|
||||
# new_pos2.x += 1
|
||||
# else:
|
||||
# new_pos.x -= 1
|
||||
|
||||
# if new_pos in self.walls:
|
||||
# return False
|
||||
|
||||
# if new_pos2 in self.boxes:
|
||||
# if not self.push_box(new_pos2, movement):
|
||||
# return False
|
||||
|
||||
# self.boxes.remove(box)
|
||||
# self.boxes.append(new_pos)
|
||||
|
||||
# return True
|
||||
|
||||
def vertical_push(self, box: Coord, movement: Coord) -> bool:
|
||||
pass
|
||||
new_pos: Coord = box + movement
|
||||
|
||||
# other_new_pos: Coord = new_pos
|
||||
# if box in self.left_boxes:
|
||||
# other_new_pos.x += 1
|
||||
# else:
|
||||
# other_new_pos.x -= 1
|
||||
|
||||
# if new_pos in self.walls or other_new_pos in self.walls:
|
||||
# return False
|
||||
|
||||
# if new_pos in self.left_boxes or new_pos in self.right_boxes:
|
||||
# if not self.vertical_push(new_pos, movement):
|
||||
# return False
|
||||
|
||||
# if other_new_pos in self.left_boxes or other_new_pos in self.right_boxes:
|
||||
# if not self.vertical_push(other_new_pos, movement):
|
||||
# return False
|
||||
|
||||
# if box in self.left_boxes:
|
||||
# self.left_boxes.remove(box)
|
||||
# self.left_boxes.append(new_pos)
|
||||
|
||||
# self.right_boxes.remove(Coord(box.x + 1, box.y))
|
||||
# self.right_boxes.append(other_new_pos)
|
||||
|
||||
# else:
|
||||
# self.right_boxes.remove(box)
|
||||
# self.right_boxes.append(new_pos)
|
||||
|
||||
# self.left_boxes.remove(Coord(box.x - 1, box.y))
|
||||
# self.left_boxes.append(other_new_pos)
|
||||
|
||||
# return True
|
||||
|
||||
# def can_push(self, box: Coord, movement: Coord) -> bool:
|
||||
# new_pos: Coord = box + movement
|
||||
|
||||
# if new_pos in self.right_boxes or new_pos in self.left_boxes:
|
||||
# return self.can_push(new_pos, movement)
|
||||
|
||||
# return new_pos in self.walls
|
||||
|
||||
# def score(self) -> int:
|
||||
# total = 0
|
||||
# for box in self.left_boxes:
|
||||
# total += 100 * box.y + box.x
|
||||
|
||||
# return total
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
with open('test.txt', 'r') as file:
|
||||
data: str = file.read()
|
||||
|
||||
warehouse_map, movements = [s.split("\n") for s in data.split("\n\n")]
|
||||
movements = ''.join(movements)
|
||||
|
||||
# Part 1
|
||||
print('<', '=' * 25, ' PART 1 ', '=' * 25, '>')
|
||||
|
||||
warehouse = Warehouse(warehouse_map)
|
||||
|
||||
print(warehouse)
|
||||
|
||||
for command in movements:
|
||||
warehouse.move_robot(command)
|
||||
print(warehouse)
|
||||
print('Score: ', warehouse.score())
|
||||
|
||||
# Part 2
|
||||
print('<', '=' * 25, ' PART 2 ', '=' * 25, '>')
|
||||
|
||||
warehouse = SecondWarehouse(warehouse_map)
|
||||
|
||||
print(warehouse)
|
||||
|
||||
# for command in movements:
|
||||
# warehouse.move_robot(command)
|
||||
# print('Movement: ', command)
|
||||
# print(warehouse)
|
||||
# input()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user