solve Day12 Part1 in python
This commit is contained in:
109
Day12/python/solution1.py
Normal file
109
Day12/python/solution1.py
Normal file
@@ -0,0 +1,109 @@
|
||||
def parse_line(line):
|
||||
"""
|
||||
Parse a line into spring states and group sizes.
|
||||
"""
|
||||
try:
|
||||
parts = line.strip().split()
|
||||
states = parts[0]
|
||||
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.
|
||||
"""
|
||||
try:
|
||||
i, size_index = 0, 0
|
||||
while i < len(states):
|
||||
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] == '#':
|
||||
count += 1
|
||||
i += 1
|
||||
|
||||
if count != group_sizes[size_index]:
|
||||
return False # Group size mismatch
|
||||
size_index += 1
|
||||
else:
|
||||
i += 1
|
||||
|
||||
return size_index == len(group_sizes) # All groups must be accounted for
|
||||
except Exception as e:
|
||||
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.
|
||||
"""
|
||||
if memo is None:
|
||||
memo = {}
|
||||
|
||||
key = (tuple(states), index)
|
||||
if key in memo:
|
||||
return memo[key]
|
||||
|
||||
if index == len(states):
|
||||
memo[key] = 1 if is_valid_configuration(states, group_sizes) else 0
|
||||
return memo[key]
|
||||
|
||||
if states[index] != '?':
|
||||
memo[key] = count_configurations(states, group_sizes, index + 1, memo)
|
||||
return memo[key]
|
||||
|
||||
count = 0
|
||||
for state in ['.', '#']:
|
||||
states[index] = state
|
||||
count += count_configurations(states, group_sizes, index + 1, memo)
|
||||
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:
|
||||
for line in file:
|
||||
states, group_sizes = parse_line(line)
|
||||
count = count_configurations(list(states), group_sizes)
|
||||
total_count += count
|
||||
print(f"Line: {line.strip()}, Possible Configurations: {count}")
|
||||
return total_count
|
||||
except Exception as e:
|
||||
print(f"Error in solve_puzzle: {e}")
|
||||
raise
|
||||
|
||||
def test():
|
||||
"""
|
||||
Test the solution with a test file.
|
||||
"""
|
||||
print("Running tests...")
|
||||
test_result = solve_puzzle("../test.txt")
|
||||
print(f"Test Result: {test_result}")
|
||||
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.
|
||||
"""
|
||||
try:
|
||||
test()
|
||||
result = solve_puzzle("../input.txt")
|
||||
print(f"Final Result: {result}")
|
||||
except Exception as e:
|
||||
print(f"Error in main: {e}")
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user