Day 22 Done
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
from copy import deepcopy
|
||||
|
||||
with open(r'advent_of_code\2023\22\input.txt', 'r') as file:
|
||||
input = file.read()
|
||||
|
||||
test_input = '''1,0,1~1,2,1
|
||||
0,0,2~2,0,2
|
||||
0,2,3~2,2,3
|
||||
0,0,4~0,2,4
|
||||
2,0,5~2,2,5
|
||||
0,1,6~2,1,6
|
||||
1,1,8~1,1,9'''
|
||||
|
||||
def parse_input(input_data):
|
||||
# Split the input data into lines
|
||||
lines = input_data.split('\n')
|
||||
|
||||
# Initialize the list of bricks
|
||||
bricks = []
|
||||
|
||||
# Parse each line into a brick
|
||||
for line in lines:
|
||||
start, end = line.split('~')
|
||||
start_x, start_y, start_z = map(int, start.split(','))
|
||||
end_x, end_y, end_z = map(int, end.split(','))
|
||||
|
||||
# Initialize the current brick
|
||||
current_brick = []
|
||||
|
||||
# Add all points in the brick to the current brick
|
||||
if start_x == end_x and start_y == end_y:
|
||||
assert start_z <= end_z
|
||||
for z in range(start_z, end_z + 1):
|
||||
current_brick.append((start_x, start_y, z))
|
||||
elif start_x == end_x and start_z == end_z:
|
||||
assert start_y <= end_y
|
||||
for y in range(start_y, end_y + 1):
|
||||
current_brick.append((start_x, y, start_z))
|
||||
elif start_y == end_y and start_z == end_z:
|
||||
assert start_x <= end_x
|
||||
for x in range(start_x, end_x + 1):
|
||||
current_brick.append((x, start_y, start_z))
|
||||
else:
|
||||
assert False
|
||||
|
||||
# Add the current brick to the list of bricks
|
||||
bricks.append(current_brick)
|
||||
|
||||
return bricks
|
||||
|
||||
def move_bricks_down(bricks):
|
||||
# Initialize the set of seen points
|
||||
seen_points = set()
|
||||
|
||||
# Add all points in the bricks to the set of seen points
|
||||
for brick in bricks:
|
||||
for point in brick:
|
||||
seen_points.add(point)
|
||||
|
||||
# Move all bricks down until they can't move anymore
|
||||
while True:
|
||||
moved = False
|
||||
for i, brick in enumerate(bricks):
|
||||
can_move = True
|
||||
for x, y, z in brick:
|
||||
if z == 1 or ((x, y, z - 1) in seen_points and (x, y, z - 1) not in brick):
|
||||
can_move = False
|
||||
if can_move:
|
||||
moved = True
|
||||
for point in brick:
|
||||
seen_points.discard(point)
|
||||
seen_points.add((point[0], point[1], point[2] - 1))
|
||||
bricks[i] = [(x, y, z - 1) for x, y, z in brick]
|
||||
if not moved:
|
||||
break
|
||||
|
||||
return bricks, seen_points
|
||||
|
||||
def count_stable_bricks(bricks, seen_points):
|
||||
|
||||
# Initialize the counts of stable bricks and fallen bricks
|
||||
stable_bricks_count = 0
|
||||
|
||||
# Check each brick
|
||||
for i, brick in enumerate(bricks):
|
||||
# Make a copy of the seen points and bricks
|
||||
current_seen_points = deepcopy(seen_points)
|
||||
current_bricks = deepcopy(bricks)
|
||||
|
||||
# Remove the current brick from the seen points
|
||||
for point in brick:
|
||||
current_seen_points.discard(point)
|
||||
|
||||
# Initialize the set of fallen bricks
|
||||
fallen_bricks = set()
|
||||
|
||||
# Move all other bricks down until they can't move anymore
|
||||
while True:
|
||||
moved = False
|
||||
for j, other_brick in enumerate(current_bricks):
|
||||
if j == i:
|
||||
continue
|
||||
can_move = True
|
||||
for x, y, z in other_brick:
|
||||
if z == 1 or ((x, y, z - 1) in current_seen_points and (x, y, z - 1) not in other_brick):
|
||||
can_move = False
|
||||
if can_move:
|
||||
fallen_bricks.add(j)
|
||||
for point in other_brick:
|
||||
current_seen_points.discard(point)
|
||||
current_seen_points.add((point[0], point[1], point[2] - 1))
|
||||
current_bricks[j] = [(x, y, z - 1) for x, y, z in other_brick]
|
||||
moved = True
|
||||
if not moved:
|
||||
break
|
||||
|
||||
# Update the counts of stable bricks and fallen bricks
|
||||
if len(fallen_bricks) == 0:
|
||||
stable_bricks_count += 1
|
||||
|
||||
return stable_bricks_count
|
||||
|
||||
def main():
|
||||
input_data = input
|
||||
bricks = parse_input(input_data)
|
||||
bricks, seen_points = move_bricks_down(bricks)
|
||||
stable_bricks_count = count_stable_bricks(bricks, seen_points)
|
||||
print(stable_bricks_count)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,133 @@
|
||||
from copy import deepcopy
|
||||
|
||||
with open(r'advent_of_code\2023\22\input.txt', 'r') as file:
|
||||
input = file.read()
|
||||
|
||||
test_input = '''1,0,1~1,2,1
|
||||
0,0,2~2,0,2
|
||||
0,2,3~2,2,3
|
||||
0,0,4~0,2,4
|
||||
2,0,5~2,2,5
|
||||
0,1,6~2,1,6
|
||||
1,1,8~1,1,9'''
|
||||
|
||||
def parse_input(input_data):
|
||||
# Split the input data into lines
|
||||
lines = input_data.split('\n')
|
||||
|
||||
# Initialize the list of bricks
|
||||
bricks = []
|
||||
|
||||
# Parse each line into a brick
|
||||
for line in lines:
|
||||
start, end = line.split('~')
|
||||
start_x, start_y, start_z = map(int, start.split(','))
|
||||
end_x, end_y, end_z = map(int, end.split(','))
|
||||
|
||||
# Initialize the current brick
|
||||
current_brick = []
|
||||
|
||||
# Add all points in the brick to the current brick
|
||||
if start_x == end_x and start_y == end_y:
|
||||
assert start_z <= end_z
|
||||
for z in range(start_z, end_z + 1):
|
||||
current_brick.append((start_x, start_y, z))
|
||||
elif start_x == end_x and start_z == end_z:
|
||||
assert start_y <= end_y
|
||||
for y in range(start_y, end_y + 1):
|
||||
current_brick.append((start_x, y, start_z))
|
||||
elif start_y == end_y and start_z == end_z:
|
||||
assert start_x <= end_x
|
||||
for x in range(start_x, end_x + 1):
|
||||
current_brick.append((x, start_y, start_z))
|
||||
else:
|
||||
assert False
|
||||
|
||||
# Add the current brick to the list of bricks
|
||||
bricks.append(current_brick)
|
||||
|
||||
return bricks
|
||||
|
||||
def move_bricks_down(bricks):
|
||||
# Initialize the set of seen points
|
||||
seen_points = set()
|
||||
|
||||
# Add all points in the bricks to the set of seen points
|
||||
for brick in bricks:
|
||||
for point in brick:
|
||||
seen_points.add(point)
|
||||
|
||||
# Move all bricks down until they can't move anymore
|
||||
while True:
|
||||
moved = False
|
||||
for i, brick in enumerate(bricks):
|
||||
can_move = True
|
||||
for x, y, z in brick:
|
||||
if z == 1 or ((x, y, z - 1) in seen_points and (x, y, z - 1) not in brick):
|
||||
can_move = False
|
||||
if can_move:
|
||||
moved = True
|
||||
for point in brick:
|
||||
seen_points.discard(point)
|
||||
seen_points.add((point[0], point[1], point[2] - 1))
|
||||
bricks[i] = [(x, y, z - 1) for x, y, z in brick]
|
||||
if not moved:
|
||||
break
|
||||
|
||||
return bricks, seen_points
|
||||
|
||||
def count_stable_bricks(bricks, seen_points):
|
||||
|
||||
# Initialize the counts of stable bricks and fallen bricks
|
||||
stable_bricks_count = 0
|
||||
fallen_bricks_count = 0
|
||||
|
||||
# Check each brick
|
||||
for i, brick in enumerate(bricks):
|
||||
# Make a copy of the seen points and bricks
|
||||
current_seen_points = deepcopy(seen_points)
|
||||
current_bricks = deepcopy(bricks)
|
||||
|
||||
# Remove the current brick from the seen points
|
||||
for point in brick:
|
||||
current_seen_points.discard(point)
|
||||
|
||||
# Initialize the set of fallen bricks
|
||||
fallen_bricks = set()
|
||||
|
||||
# Move all other bricks down until they can't move anymore
|
||||
while True:
|
||||
moved = False
|
||||
for j, other_brick in enumerate(current_bricks):
|
||||
if j == i:
|
||||
continue
|
||||
can_move = True
|
||||
for x, y, z in other_brick:
|
||||
if z == 1 or ((x, y, z - 1) in current_seen_points and (x, y, z - 1) not in other_brick):
|
||||
can_move = False
|
||||
if can_move:
|
||||
fallen_bricks.add(j)
|
||||
for point in other_brick:
|
||||
current_seen_points.discard(point)
|
||||
current_seen_points.add((point[0], point[1], point[2] - 1))
|
||||
current_bricks[j] = [(x, y, z - 1) for x, y, z in other_brick]
|
||||
moved = True
|
||||
if not moved:
|
||||
break
|
||||
|
||||
# Update the counts of stable bricks and fallen bricks
|
||||
if len(fallen_bricks) == 0:
|
||||
stable_bricks_count += 1
|
||||
fallen_bricks_count += len(fallen_bricks)
|
||||
|
||||
return stable_bricks_count, fallen_bricks_count
|
||||
|
||||
def main():
|
||||
input_data = input
|
||||
bricks = parse_input(input_data)
|
||||
bricks, seen_points = move_bricks_down(bricks)
|
||||
stable_bricks_count, fallen_bricks_count = count_stable_bricks(bricks, seen_points)
|
||||
print(stable_bricks_count)
|
||||
print(fallen_bricks_count)
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user