feat: solve day 23 part 2
This commit is contained in:
parent
ad19c6c3f0
commit
da96bf0fb9
58
23/main.py
58
23/main.py
@ -23,8 +23,10 @@ def simulate(cups: list[int], moves: int):
|
|||||||
|
|
||||||
current_cup_label = cups[0]
|
current_cup_label = cups[0]
|
||||||
for _ in range(moves):
|
for _ in range(moves):
|
||||||
|
# take 3 cups
|
||||||
taken_cups = take_cups(cups, cups.index(current_cup_label)+1, 3)
|
taken_cups = take_cups(cups, cups.index(current_cup_label)+1, 3)
|
||||||
|
|
||||||
|
# determine destination cup
|
||||||
destination_label = current_cup_label - 1
|
destination_label = current_cup_label - 1
|
||||||
while destination_label not in cups:
|
while destination_label not in cups:
|
||||||
destination_label -= 1
|
destination_label -= 1
|
||||||
@ -32,10 +34,40 @@ def simulate(cups: list[int], moves: int):
|
|||||||
destination_label = max_value
|
destination_label = max_value
|
||||||
destination = cups.index(destination_label)
|
destination = cups.index(destination_label)
|
||||||
|
|
||||||
|
# put back the 3 taken cups
|
||||||
put_cups(cups, destination + 1, taken_cups)
|
put_cups(cups, destination + 1, taken_cups)
|
||||||
|
|
||||||
|
# move current cup
|
||||||
current_cup_label = cups[(cups.index(current_cup_label) + 1) % len(cups)]
|
current_cup_label = cups[(cups.index(current_cup_label) + 1) % len(cups)]
|
||||||
|
|
||||||
|
def simulate_lookup(next_cup_lookup: list[int], current_cup: int, moves: int):
|
||||||
|
max_value = len(next_cup_lookup) - 1
|
||||||
|
min_value = 1
|
||||||
|
|
||||||
|
for _ in range(moves):
|
||||||
|
# take 3 cups
|
||||||
|
taken_cup1 = next_cup_lookup[current_cup]
|
||||||
|
taken_cup2 = next_cup_lookup[taken_cup1]
|
||||||
|
taken_cup3 = next_cup_lookup[taken_cup2]
|
||||||
|
|
||||||
|
# determine destination cup
|
||||||
|
destination = current_cup
|
||||||
|
while True:
|
||||||
|
destination -= 1
|
||||||
|
if destination < min_value:
|
||||||
|
destination = max_value
|
||||||
|
if destination != taken_cup1 and destination != taken_cup2 and destination != taken_cup3:
|
||||||
|
break
|
||||||
|
|
||||||
|
# put back the 3 taken cups
|
||||||
|
next_cup_lookup[current_cup] = next_cup_lookup[taken_cup3]
|
||||||
|
after_destination = next_cup_lookup[destination]
|
||||||
|
next_cup_lookup[taken_cup3] = after_destination
|
||||||
|
next_cup_lookup[destination] = taken_cup1
|
||||||
|
|
||||||
|
# move current cup
|
||||||
|
current_cup = next_cup_lookup[current_cup]
|
||||||
|
|
||||||
def part1(cups: list[int]) -> str:
|
def part1(cups: list[int]) -> str:
|
||||||
simulate(cups, 100)
|
simulate(cups, 100)
|
||||||
|
|
||||||
@ -43,18 +75,28 @@ def part1(cups: list[int]) -> str:
|
|||||||
return "".join(map(str, cups[num1_index+1:])) + "".join(map(str, cups[:num1_index]))
|
return "".join(map(str, cups[num1_index+1:])) + "".join(map(str, cups[:num1_index]))
|
||||||
|
|
||||||
def part2(cups: list[int]) -> int:
|
def part2(cups: list[int]) -> int:
|
||||||
for value in range(max(cups), 1_000_000 + 1):
|
# create lookup table for the next value
|
||||||
cups.append(value)
|
next_cup_lookup: list[int] = [0]*(len(cups)+1)
|
||||||
|
max_value = max(cups)
|
||||||
|
cups.append(max_value+1)
|
||||||
|
for i in range(len(cups)-1):
|
||||||
|
cup = cups[i]
|
||||||
|
next_cup = cups[i+1]
|
||||||
|
next_cup_lookup[cup] = next_cup
|
||||||
|
|
||||||
simulate(cups, 1_00)
|
for next_cup in range(max_value+2, 1_000_000+1):
|
||||||
# simulate(cups, 10_000_000)
|
next_cup_lookup.append(next_cup)
|
||||||
|
next_cup_lookup.append(cups[0])
|
||||||
|
|
||||||
num1_index = cups.index(1)
|
# perform the simulation
|
||||||
star1 = cups[(num1_index + 1) % len(cups)]
|
simulate_lookup(next_cup_lookup, cups[0], 10_000_000)
|
||||||
star2 = cups[(num1_index + 2) % len(cups)]
|
|
||||||
|
# calculate the final result
|
||||||
|
star1 = next_cup_lookup[1]
|
||||||
|
star2 = next_cup_lookup[star1]
|
||||||
return star1 * star2
|
return star1 * star2
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cups = read_input("test.txt")
|
cups = read_input("input.txt")
|
||||||
print("part1: ", part1(cups.copy()))
|
print("part1: ", part1(cups.copy()))
|
||||||
print("part2: ", part2(cups.copy()))
|
print("part2: ", part2(cups.copy()))
|
||||||
|
Loading…
Reference in New Issue
Block a user