solve Day12 in python

This commit is contained in:
2023-12-12 19:35:31 +01:00
parent 5fe2e22a49
commit 28c7ce3b41
4 changed files with 131 additions and 11 deletions

View File

@@ -5,12 +5,13 @@ def parse_line(line):
try:
parts = line.strip().split()
states = parts[0]
group_sizes = [int(x) for x in parts[1].split(',')]
group_sizes = [int(x) for x in parts[1].split(",")]
return states, group_sizes
except Exception as e:
print(f"Error parsing line '{line}': {e}")
raise
def is_valid_configuration(states, group_sizes):
"""
Check if a given configuration of springs is valid based on group sizes.
@@ -18,12 +19,12 @@ def is_valid_configuration(states, group_sizes):
try:
i, size_index = 0, 0
while i < len(states):
if states[i] == '#':
if states[i] == "#":
if size_index >= len(group_sizes):
return False # More broken springs than groups
count = 0
while i < len(states) and states[i] == '#':
while i < len(states) and states[i] == "#":
count += 1
i += 1
@@ -38,6 +39,7 @@ def is_valid_configuration(states, group_sizes):
print(f"Error in is_valid_configuration: {e}")
raise
def count_configurations(states, group_sizes, index=0, memo=None):
"""
Count the number of valid configurations using backtracking and memoization.
@@ -53,26 +55,27 @@ def count_configurations(states, group_sizes, index=0, memo=None):
memo[key] = 1 if is_valid_configuration(states, group_sizes) else 0
return memo[key]
if states[index] != '?':
if states[index] != "?":
memo[key] = count_configurations(states, group_sizes, index + 1, memo)
return memo[key]
count = 0
for state in ['.', '#']:
for state in [".", "#"]:
states[index] = state
count += count_configurations(states, group_sizes, index + 1, memo)
states[index] = '?'
states[index] = "?"
memo[key] = count
return count
def solve_puzzle(file_path):
"""
Solve the puzzle for each line in the file and return the total count of configurations.
"""
try:
total_count = 0
with open(file_path, 'r') as file:
with open(file_path, "r") as file:
for line in file:
states, group_sizes = parse_line(line)
count = count_configurations(list(states), group_sizes)
@@ -83,6 +86,7 @@ def solve_puzzle(file_path):
print(f"Error in solve_puzzle: {e}")
raise
def test():
"""
Test the solution with a test file.
@@ -93,6 +97,7 @@ def test():
assert test_result == 21, f"Test failed, expected 21, got {test_result}"
print("Test passed successfully.")
def main():
"""
Main function to run the test and then solve the puzzle.
@@ -105,5 +110,6 @@ def main():
print(f"Error in main: {e}")
raise
if __name__ == "__main__":
main()

85
Day12/python/solution2.py Normal file
View File

@@ -0,0 +1,85 @@
import sys
def read_data(filepath):
"""Reads the data from the given file."""
try:
with open(filepath, "r") as file:
return file.read().strip().split("\n")
except IOError as e:
print(f"Error reading file '{filepath}': {e}")
sys.exit(1)
def unfold_record(record):
"""Unfolds the record according to the puzzle rules."""
dots, blocks = record.split()
dots = "?".join([dots] * 5)
blocks = ",".join([blocks] * 5)
return dots, [int(x) for x in blocks.split(",")]
def count_arrangements(dots, blocks, i=0, bi=0, current=0, memo=None):
"""Counts valid arrangements using dynamic programming."""
if memo is None:
memo = {}
key = (i, bi, current)
if key in memo:
return memo[key]
if i == len(dots):
if bi == len(blocks) and current == 0:
return 1
elif bi == len(blocks) - 1 and blocks[bi] == current:
return 1
else:
return 0
ans = 0
for c in [".", "#"]:
if dots[i] == c or dots[i] == "?":
if c == ".":
if current == 0:
ans += count_arrangements(dots, blocks, i + 1, bi, 0, memo)
elif current > 0 and bi < len(blocks) and blocks[bi] == current:
ans += count_arrangements(dots, blocks, i + 1, bi + 1, 0, memo)
elif c == "#":
ans += count_arrangements(dots, blocks, i + 1, bi, current + 1, memo)
memo[key] = ans
return ans
def solve_puzzle(lines):
"""Solves the puzzle for the given input lines."""
total = 0
for line in lines:
print(f"Processing: {line}")
dots, blocks = unfold_record(line)
total += count_arrangements(dots, blocks)
return total
def test_puzzle():
"""Runs the puzzle solution on test data."""
test_data = read_data("../test.txt")
print("Running tests...")
test_result = solve_puzzle(test_data)
print(f"Test result: {test_result}")
assert test_result == 525152, "Test failed!"
print("Test passed.")
def main():
"""Main function to run the puzzle solution."""
test_puzzle()
input_data = read_data("../input.txt")
print("Processing input data...")
result = solve_puzzle(input_data)
print(f"Final result: {result}")
if __name__ == "__main__":
main()