solved Day18 in python

This commit is contained in:
2023-12-18 17:49:47 +01:00
parent d654b246a3
commit 776c74fc1e
4 changed files with 265 additions and 0 deletions

101
Day18/python/solution1.py Normal file
View File

@@ -0,0 +1,101 @@
def parse_instructions(file_path):
"""Parse instructions from the given file."""
try:
with open(file_path, 'r') as file:
instructions = [line.strip().split() for line in file.readlines()]
print(f"Parsed {len(instructions)} instructions from {file_path}")
return instructions
except Exception as e:
print(f"Error reading file {file_path}: {e}")
raise
def apply_instruction(grid, position, direction, steps):
"""Apply a single instruction to the grid and update the position."""
deltas = {'U': (0, -1), 'D': (0, 1), 'L': (-1, 0), 'R': (1, 0)}
dx, dy = deltas[direction]
for _ in range(steps):
position = (position[0] + dx, position[1] + dy)
grid.add(position)
#print(f"Moved {direction} to {position}")
return position
def create_path(instructions):
"""Create the path based on the instructions."""
grid = set()
position = (0, 0)
grid.add(position)
for instruction in instructions:
direction, steps = instruction[0], int(instruction[1])
print(f"Applying instruction: {direction} {steps}")
position = apply_instruction(grid, position, direction, steps)
return grid
def flood_fill(grid, bounds):
"""Perform flood-fill to find cells outside the path."""
filled = set()
to_fill = [(bounds[0], y) for y in range(bounds[2], bounds[3] + 1)] \
+ [(bounds[1], y) for y in range(bounds[2], bounds[3] + 1)] \
+ [(x, bounds[2]) for x in range(bounds[0], bounds[1] + 1)] \
+ [(x, bounds[3]) for x in range(bounds[0], bounds[1] + 1)]
while to_fill:
x, y = to_fill.pop()
if (x, y) in filled or (x, y) in grid:
continue
filled.add((x, y))
if x > bounds[0]: to_fill.append((x - 1, y))
if x < bounds[1]: to_fill.append((x + 1, y))
if y > bounds[2]: to_fill.append((x, y - 1))
if y < bounds[3]: to_fill.append((x, y + 1))
return filled
def calculate_area(grid):
"""Calculate the area inside the loop."""
min_x = min(grid, key=lambda x: x[0])[0]
max_x = max(grid, key=lambda x: x[0])[0]
min_y = min(grid, key=lambda x: x[1])[1]
max_y = max(grid, key=lambda x: x[1])[1]
bounds = (min_x, max_x, min_y, max_y)
outside_area = flood_fill(grid, bounds)
total_area = (max_x - min_x + 1) * (max_y - min_y + 1)
inside_area = total_area - len(outside_area)
return inside_area
def run_test(test_file):
"""Run the algorithm with test input."""
try:
instructions = parse_instructions(test_file)
grid = create_path(instructions)
area = calculate_area(grid)
assert area == 62, f"Test failed. Expected 62 but got {area} with grid {grid}"
print("Test passed successfully.")
return True
except AssertionError as e:
print(f"Assertion Error: {e}")
return False
def main():
"""Main function to run the puzzle solution."""
test_file = "../test.txt"
input_file = "../input.txt"
# Run test
if run_test(test_file):
# Process actual puzzle input
try:
instructions = parse_instructions(input_file)
grid = create_path(instructions)
area = calculate_area(grid)
print(f"Puzzle result (area): {area}")
except Exception as e:
print(f"Error during puzzle execution: {e}")
else:
print("Test failed. Halting execution.")
if __name__ == "__main__":
main()

65
Day18/python/solution2.py Normal file
View File

@@ -0,0 +1,65 @@
def parse_instructions(file_path):
"""Parse instructions from the given file."""
try:
with open(file_path, 'r') as file:
lines = file.read().splitlines()
print(f"Parsed {len(lines)} instructions from {file_path}")
return lines
except Exception as e:
print(f"Error reading file {file_path}: {e}")
raise
def calculate_area(lines):
"""Calculate the area inside the loop defined by the instructions."""
DIRECTIONS = [(0, 1), (1, 0), (0, -1), (-1, 0)]
points = [(0, 0)]
boundary = 0
for line in lines:
*_, color = line.split()
instructions = color[2:-1]
dr, dc = DIRECTIONS[int(instructions[-1])]
steps = int(instructions[:-1], 16)
boundary += steps
row, column = points[-1]
points.append((row + dr * steps, column + dc * steps))
area = abs(
sum(x1 * y2 - x2 * y1 for (x1, y1), (x2, y2) in zip(points, points[1:] + points[:1]))
) // 2 + boundary // 2 + 1
return area
def run_test(test_file, expected_result):
"""Run the algorithm with test input and compare with the expected result."""
try:
lines = parse_instructions(test_file)
calculated_area = calculate_area(lines)
assert calculated_area == expected_result, f"Test failed, expected {expected_result}, got {calculated_area}"
print(f"Test passed, area: {calculated_area}")
except AssertionError as e:
print(e)
raise
except Exception as e:
print(f"Error during test execution: {e}")
raise
def main():
"""Main function to run the puzzle solution."""
test_file = "../test.txt"
input_file = "../input.txt"
expected_test_area = 952408144115 # Replace with the correct expected area for the test
# Run test
try:
run_test(test_file, expected_test_area)
# Process actual puzzle input
lines = parse_instructions(input_file)
area = calculate_area(lines)
print(f"Puzzle result (area): {area}")
except Exception as e:
print(f"Execution halted due to error: {e}")
if __name__ == "__main__":
main()