From 2b97334a8d08a3f6054829b1859a839ad418e1ac Mon Sep 17 00:00:00 2001 From: wieerwill Date: Mon, 11 Dec 2023 09:45:45 +0100 Subject: [PATCH] solve Day11 with python --- Day11/README.md | 104 ++++++++++++++++++++++++++++++++++++++ Day11/python/solution1.py | 58 +++++++++++++++++++++ Day11/test.txt | 10 ++++ README.md | 8 +-- 4 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 Day11/README.md create mode 100644 Day11/python/solution1.py create mode 100644 Day11/test.txt diff --git a/Day11/README.md b/Day11/README.md new file mode 100644 index 0000000..d1b32fe --- /dev/null +++ b/Day11/README.md @@ -0,0 +1,104 @@ +# Day 11: Cosmic Expansion +## Part One +You continue following signs for "Hot Springs" and eventually come across an observatory. The Elf within turns out to be a researcher studying cosmic expansion using the giant telescope here. + +He doesn't know anything about the missing machine parts; he's only visiting for this research project. However, he confirms that the hot springs are the next-closest area likely to have people; he'll even take you straight there once he's done with today's observation analysis. + +Maybe you can help him with the analysis to speed things up? + +The researcher has collected a bunch of data and compiled the data into a single giant image (your puzzle input). The image includes empty space (.) and galaxies (#). For example: +``` +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... +``` +The researcher is trying to figure out the sum of the lengths of the shortest path between every pair of galaxies. However, there's a catch: the universe expanded in the time it took the light from those galaxies to reach the observatory. + +Due to something involving gravitational effects, only some space expands. In fact, the result is that any rows or columns that contain no galaxies should all actually be twice as big. + +In the above example, three columns and two rows contain no galaxies: +``` + v v v + ...#...... + .......#.. + #......... +>..........< + ......#... + .#........ + .........# +>..........< + .......#.. + #...#..... + ^ ^ ^ +``` +These rows and columns need to be twice as big; the result of cosmic expansion therefore looks like this: +``` +....#........ +.........#... +#............ +............. +............. +........#.... +.#........... +............# +............. +............. +.........#... +#....#....... +``` +Equipped with this expanded universe, the shortest path between every pair of galaxies can be found. It can help to assign every galaxy a unique number: +``` +....1........ +.........2... +3............ +............. +............. +........4.... +.5........... +............6 +............. +............. +.........7... +8....9....... +``` +In these 9 galaxies, there are 36 pairs. Only count each pair once; order within the pair doesn't matter. For each pair, find any shortest path between the two galaxies using only steps that move up, down, left, or right exactly one . or # at a time. (The shortest path between two galaxies is allowed to pass through another galaxy.) + +For example, here is one of the shortest paths between galaxies 5 and 9: +``` +....1........ +.........2... +3............ +............. +............. +........4.... +.5........... +.##.........6 +..##......... +...##........ +....##...7... +8....9....... +``` +This path has length 9 because it takes a minimum of nine steps to get from galaxy 5 to galaxy 9 (the eight locations marked # plus the step onto galaxy 9 itself). Here are some other example shortest path lengths: +- Between galaxy 1 and galaxy 7: 15 +- Between galaxy 3 and galaxy 6: 17 +- Between galaxy 8 and galaxy 9: 5 + +In this example, after expanding the universe, the sum of the shortest path between all 36 pairs of galaxies is 374. + +Expand the universe, then find the length of the shortest path between every pair of galaxies. What is the sum of these lengths? + +## Part Two +The galaxies are much older (and thus much farther apart) than the researcher initially estimated. + +Now, instead of the expansion you did before, make each empty row or column one million times larger. That is, each empty row should be replaced with 1000000 empty rows, and each empty column should be replaced with 1000000 empty columns. + +(In the example above, if each empty row or column were merely 10 times larger, the sum of the shortest paths between every pair of galaxies would be 1030. If each empty row or column were merely 100 times larger, the sum of the shortest paths between every pair of galaxies would be 8410. However, your universe will need to expand far beyond these values.) + +Starting with the same initial image, expand the universe according to these new rules, then find the length of the shortest path between every pair of galaxies. What is the sum of these lengths? \ No newline at end of file diff --git a/Day11/python/solution1.py b/Day11/python/solution1.py new file mode 100644 index 0000000..c1943b5 --- /dev/null +++ b/Day11/python/solution1.py @@ -0,0 +1,58 @@ +import sys + +def read_grid(file_path): + """Reads the grid from the file and returns it as a 2D list.""" + try: + with open(file_path, 'r') as file: + return [list(line.strip()) for line in file] + except Exception as e: + print(f"Error reading file {file_path}: {e}") + sys.exit(1) + +def find_empty_rows_and_cols(grid): + """Finds empty rows and columns in the grid.""" + empty_rows = [i for i, row in enumerate(grid) if '#' not in row] + empty_cols = [j for j in range(len(grid[0])) if all(row[j] == '.' for row in grid)] + return empty_rows, empty_cols + +def locate_galaxies(grid): + """Locates the coordinates of galaxies in the grid.""" + return [(r, c) for r, row in enumerate(grid) for c, val in enumerate(row) if val == '#'] + +def calculate_distances(grid, galaxies, expansion_factor): + """Calculates the sum of distances between all pairs of galaxies.""" + empty_rows, empty_cols = find_empty_rows_and_cols(grid) + total_distance = 0 + + for i, (r1, c1) in enumerate(galaxies): + for r2, c2 in galaxies[i:]: + distance = abs(r2 - r1) + abs(c2 - c1) + distance += sum(expansion_factor for er in empty_rows if min(r1, r2) <= er <= max(r1, r2)) + distance += sum(expansion_factor for ec in empty_cols if min(c1, c2) <= ec <= max(c1, c2)) + total_distance += distance + + return total_distance + +def run_test(): + """Runs the test using the test file.""" + test_grid = read_grid("../test.txt") + test_galaxies = locate_galaxies(test_grid) + test_result = calculate_distances(test_grid, test_galaxies, 1) + assert test_result == 374, f"Test failed: Expected 374, got {test_result}" + print("Test passed successfully.") + +def main(): + print("Starting puzzle solution...") + + grid = read_grid("../input.txt") + galaxies = locate_galaxies(grid) + + for part2 in [False, True]: + expansion_factor = 10**6 - 1 if part2 else 1 + print(f"Calculating distances for part {'2' if part2 else '1'}...") + total_distance = calculate_distances(grid, galaxies, expansion_factor) + print(f"Total distance for part {'2' if part2 else '1'}: {total_distance}") + +if __name__ == "__main__": + run_test() + main() diff --git a/Day11/test.txt b/Day11/test.txt new file mode 100644 index 0000000..986aad4 --- /dev/null +++ b/Day11/test.txt @@ -0,0 +1,10 @@ +...#...... +.......#.. +#......... +.......... +......#... +.#........ +.........# +.......... +.......#.. +#...#..... diff --git a/README.md b/README.md index dd22311..aa14f27 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # 🎄 Advent of Code 2023 🎄 ![Build Status](https://github.com/wieerwill/advent_of_code_2023/actions/workflows/lint.yml/badge.svg) -![Coverage](https://codecov.io/gh/wieerwill/advent_of_code_2023/branch/main/graph/badge.svg) -![Dependencies Status](https://david-dm.org/wieerwill/advent_of_code_2023.svg) +![Completed](https://img.shields.io/badge/days%20completed-11-red) +![Stars](https://img.shields.io/badge/stars%20⭐-22-yellow) ![License](https://img.shields.io/github/license/wieerwill/advent_of_code_2023.svg) Welcome to my repository where I share my solutions for the [Advent of Code 2023](https://adventofcode.com/2023). Advent of Code is an annual online event where participants solve a series of programming puzzles released daily from December 1st until December 25th. Each puzzle is a fun and unique challenge designed to test problem-solving skills. @@ -41,8 +41,8 @@ I aim to complete each day's puzzle on the same day, but as with any challenge, | 07 | ✅ | ✅ | [Day07 README](/Day07/README.md) | | 08 | ✅ | ✅ | [Day08 README](/Day08/README.md) | | 09 | ✅ | ✅ | [Day09 README](/Day09/README.md) | -| 10 | ❓ | ❓ | [Day10 README](/Day10/README.md) | -| 11 | ❓ | ❓ | [Day11 README](/Day11/README.md) | +| 10 | ✅ | ✅ | [Day10 README](/Day10/README.md) | +| 11 | ✅ | ✅ | [Day11 README](/Day11/README.md) | | 12 | ❓ | ❓ | [Day12 README](/Day12/README.md) | | 13 | ❓ | ❓ | [Day13 README](/Day13/README.md) | | 14 | ❓ | ❓ | [Day14 README](/Day14/README.md) |