From 01503d10591d8327b08f6ffe04d4ec42b82208ce Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Sun, 15 Dec 2024 18:08:44 +0100 Subject: [PATCH] add 2024/15.1 --- 2024/15/main.py | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 2024/15/main.py diff --git a/2024/15/main.py b/2024/15/main.py new file mode 100644 index 0000000..d37a00c --- /dev/null +++ b/2024/15/main.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# -*- encoding: utf-8; py-indent-offset: 4 -*- + +# Author: Sebastian Mark +# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de) + +# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string + +import re +import copy + +DIRECTION = { + "^": (-1, 0), + "v": (1, 0), + "<": (0, -1), + ">": (0, 1), +} + + +def readinput(): + with open("input", "r", encoding="utf-8") as file: + lines = file.readlines() + sep = lines.index("\n") + + warehouse = [] + for line in lines[:sep]: + warehouse.append(list(line.strip())) + + directions = "" + for line in lines[sep + 1 :]: + directions += line.strip() + + return warehouse, directions + + +def find_robot(warehouse: list) -> tuple: + for y, line in enumerate(warehouse): + try: + x = line.index("@") + except ValueError: + continue + + return (y, x) + + +def run_robot_run(warehouse: list, robot: tuple, directions: list) -> list: + sorted_warehouse = copy.deepcopy(warehouse) + roboty, robotx = robot + + for d in directions: + dy, dx = DIRECTION[d] + + nxty = roboty + dy + nxtx = robotx + dx + + # check for border in front of robot + if sorted_warehouse[nxty][nxtx] == "#": + continue + + # check stack of boxes + boxes = [] + bxchky, bxchkx = nxty, nxtx + while sorted_warehouse[bxchky][bxchkx] == "O": + boxes.append((bxchky, bxchkx)) + bxchky += dy + bxchkx += dx + + # check for border after last box + if sorted_warehouse[bxchky][bxchkx] == "#": + continue + + # move boxes + for box in boxes: + sorted_warehouse[box[0] + dy][box[1] + dx] = "O" + + # move robot + sorted_warehouse[roboty][robotx] = "." + sorted_warehouse[nxty][nxtx] = "@" + roboty, robotx = nxty, nxtx + + return sorted_warehouse + + +def calc_gps_sum(warehouse: list) -> int: + gps_sum = 0 + for y, line in enumerate(warehouse): + boxes = re.finditer("O", "".join(line)) + for box in boxes: + gps_sum += 100 * y + box.start() + + return gps_sum + + +def print_area(area: list): + for line in area: + print("".join(line)) + + +def main(): + warehouse, directions = readinput() + + # part 1 + robot = find_robot(warehouse) + unclutterd_warehouse = run_robot_run(warehouse, robot, directions) + gps_sum = calc_gps_sum(unclutterd_warehouse) + print("GPS sum: %d" % gps_sum) + + +if __name__ == "__main__": + main()