76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
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()
|