adding puzzle Day22
This commit is contained in:
132
Day22/python/solution1.py
Normal file
132
Day22/python/solution1.py
Normal file
@@ -0,0 +1,132 @@
|
||||
import sys
|
||||
|
||||
def parse_input(file_path):
|
||||
"""Reads the input from a file and returns it as a list of bricks."""
|
||||
print("Parsing input...")
|
||||
try:
|
||||
with open(file_path, "r") as file:
|
||||
bricks = []
|
||||
for line in file:
|
||||
st, ed = line.split('~')
|
||||
sx, sy, sz = [int(x) for x in st.split(',')]
|
||||
ex, ey, ez = [int(x) for x in ed.split(',')]
|
||||
brick = []
|
||||
if sx == ex and sy == ey:
|
||||
assert sz <= ez
|
||||
for z in range(sz, ez + 1):
|
||||
brick.append((sx, sy, z))
|
||||
elif sx == ex and sz == ez:
|
||||
assert sy <= ey
|
||||
for y in range(sy, ey + 1):
|
||||
brick.append((sx, y, sz))
|
||||
elif sy == ey and sz == ez:
|
||||
assert sx <= ex
|
||||
for x in range(sx, ex + 1):
|
||||
brick.append((x, sy, sz))
|
||||
else:
|
||||
assert False
|
||||
assert len(brick) >= 1
|
||||
bricks.append(brick)
|
||||
print("File parsed successfully.")
|
||||
return bricks
|
||||
except FileNotFoundError as fnfe:
|
||||
print(f"File not found error: {fnfe}")
|
||||
except Exception as e:
|
||||
print(f"File error: {e}")
|
||||
|
||||
def simulate_settling(bricks):
|
||||
"""Simulates the bricks falling into place."""
|
||||
print("Simulating settling of bricks...")
|
||||
seen = set()
|
||||
for brick in bricks:
|
||||
for (x, y, z) in brick:
|
||||
seen.add((x, y, z))
|
||||
|
||||
while True:
|
||||
any_change = False
|
||||
for i, brick in enumerate(bricks):
|
||||
ok_to_fall = True
|
||||
for (x, y, z) in brick:
|
||||
if z == 1 or ((x, y, z - 1) in seen and (x, y, z - 1) not in brick):
|
||||
ok_to_fall = False
|
||||
break
|
||||
if ok_to_fall:
|
||||
any_change = True
|
||||
for (x, y, z) in brick:
|
||||
seen.discard((x, y, z))
|
||||
seen.add((x, y, z - 1))
|
||||
bricks[i] = [(x, y, z - 1) for (x, y, z) in brick]
|
||||
if not any_change:
|
||||
break
|
||||
print("Settling simulation completed.")
|
||||
return bricks, seen
|
||||
|
||||
def find_safe_disintegrations(bricks, seen):
|
||||
"""Determines which bricks can be safely disintegrated."""
|
||||
print("Identifying safe disintegrations...")
|
||||
original_seen = seen.copy()
|
||||
original_bricks = bricks.copy()
|
||||
safe_count = 0
|
||||
|
||||
for i, brick in enumerate(original_bricks):
|
||||
temp_seen = original_seen.copy()
|
||||
temp_bricks = original_bricks.copy()
|
||||
|
||||
for (x, y, z) in brick:
|
||||
temp_seen.discard((x, y, z))
|
||||
|
||||
while True:
|
||||
any_change = False
|
||||
for j, temp_brick in enumerate(temp_bricks):
|
||||
if j == i:
|
||||
continue
|
||||
ok_to_fall = True
|
||||
for (x, y, z) in temp_brick:
|
||||
if z == 1 or ((x, y, z - 1) in temp_seen and (x, y, z - 1) not in temp_brick):
|
||||
ok_to_fall = False
|
||||
break
|
||||
if ok_to_fall:
|
||||
for (x, y, z) in temp_brick:
|
||||
temp_seen.discard((x, y, z))
|
||||
temp_seen.add((x, y, z - 1))
|
||||
temp_bricks[j] = [(x, y, z - 1) for (x, y, z) in temp_brick]
|
||||
any_change = True
|
||||
if not any_change:
|
||||
break
|
||||
|
||||
# If no bricks fell, increment safe count
|
||||
if all(j != i for j in temp_bricks):
|
||||
safe_count += 1
|
||||
|
||||
print(f"Found {safe_count} bricks that can be safely disintegrated.")
|
||||
return safe_count
|
||||
|
||||
def process_puzzle(bricks):
|
||||
"""Processes the puzzle solution algorithm."""
|
||||
settled_bricks, seen = simulate_settling(bricks)
|
||||
return find_safe_disintegrations(settled_bricks, seen)
|
||||
|
||||
def run_test():
|
||||
"""Runs the algorithm with the test data and asserts the result."""
|
||||
print("Running test...")
|
||||
test_bricks = parse_input("../test.txt")
|
||||
expected_result = 16 # Assuming expected result is 16
|
||||
test_result = process_puzzle(test_bricks)
|
||||
assert test_result == expected_result, f"Test failed: Expected {expected_result}, got {test_result}"
|
||||
print("Test passed successfully.")
|
||||
|
||||
def main():
|
||||
"""Main function to run the algorithm with the actual puzzle data."""
|
||||
try:
|
||||
run_test()
|
||||
print("Start processing input puzzle...")
|
||||
puzzle_bricks = parse_input("../input.txt")
|
||||
result = process_puzzle(puzzle_bricks)
|
||||
print(f"Final Result: {result}")
|
||||
except AssertionError as ae:
|
||||
print(f"Assertion Error: {ae}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user