Solved 2024/11 P2

This commit is contained in:
FrederikBaerentsen 2024-12-11 18:44:27 +01:00
parent 8092c555a3
commit 0a76f38bb3
3 changed files with 104 additions and 63 deletions

View File

@ -82,8 +82,6 @@ will you have after blinking 25 times?*
Your puzzle answer was `211306`. Your puzzle answer was `211306`.
The first half of this puzzle is complete! It provides one gold star: \*
## \-\-- Part Two \-\-- {#part2} ## \-\-- Part Two \-\-- {#part2}
The Historians sure are taking a long time. To be fair, the infinite The Historians sure are taking a long time. To be fair, the infinite
@ -91,8 +89,14 @@ corridors *are* very large.
*How many stones would you have after blinking a total of 75 times?* *How many stones would you have after blinking a total of 75 times?*
Answer: Your puzzle answer was `250783680217283`.
Although it hasn\'t changed, you can still [get your puzzle Both parts of this puzzle are complete! They provide two gold stars:
\*\*
At this point, you should [return to your Advent calendar](/2024) and
try another puzzle.
If you still want to see it, you can [get your puzzle
input](11/input). input](11/input).

View File

@ -6,7 +6,7 @@ sys.path.insert(0, '../../')
from fred import list2int,get_re,nprint,lprint,loadFile from fred import list2int,get_re,nprint,lprint,loadFile
start_time = time.time() start_time = time.time()
input_f = 'test' input_f = 'input'
part = 1 part = 1
######################################### #########################################
@ -15,94 +15,130 @@ part = 1
# # # #
######################################### #########################################
def rule1(number:int): # Part 1 was first done using a list and each
if number == 0: # number in the input list was converted to ints
return 1 # then each new list was created and passed through
else: # again.
print('Number not 0, why are you here') # I also did the Part 1 using deque, but this wasn't
# any faster at all.
def rule2(number): def rule2(number):
# Convert the number to a string
num_str = str(number) num_str = str(number)
length = len(num_str) middle = len(num_str) // 2
return [int(num_str[:middle]), int(num_str[middle:])]
# Calculate the split index
middle = length // 2
# Split the number into two parts
left_part = num_str[:middle]
right_part = num_str[middle:]
#print(left_part,right_part)
return int(left_part), int(right_part)
def part1(input_f): def part1(input_f):
instructions = [] instructions = []
with open(input_f) as file: with open(input_f) as file:
instructions = list2int(file.readline().strip().split(' ')) instructions = list2int(file.readline().strip().split(' '))
new_inst = [] new_inst = []
for x in range(25): for x in range(25):
for idx,inst in enumerate(instructions): for idx,inst in enumerate(instructions):
# Rule 1
if inst == 0: if inst == 0:
new_inst.append(1) new_inst.append(1)
else: else:
# Rule 2 if len(list(str(inst))) % 2 == 0:
t = list(str(inst))
if len(t) % 2 == 0:
new_inst += rule2(inst) new_inst += rule2(inst)
else: else:
# Rule 3
new_inst.append(instructions[idx] * 2024) new_inst.append(instructions[idx] * 2024)
instructions = new_inst instructions = new_inst
new_inst = [] new_inst = []
print(len(instructions)) return len(instructions)
def part1_dq(input_f):
dq = []
with open(input_f) as file:
dq = deque(file.readline().strip().split(' '))
new_inst = deque([])
for r in range(25):
i = 0
while_time = time.time()
while i < len(dq):
if dq[i] == 0:
new_inst.append(1)
else:
if len(str(dq[i])) % 2 == 0:
x = rule2(dq[i])
new_inst.append(x[0])
new_inst.append(x[1])
else:
new_inst.append(int(dq[i]) * 2024)
i += 1
dq = new_inst
new_inst = deque([])
return len(dq)
start_time = time.time() start_time = time.time()
part1(input_f) print('Part 1:',part1(input_f), '\t\t\t(list)\t', round((time.time() - start_time)*1000), 'ms')
print("--- %s seconds ---" % (time.time() - start_time)) start_time = time.time()
print('Part 1:',part1(input_f), '\t\t\t(deque)\t', round((time.time() - start_time)*1000), 'ms')
######################################### #########################################
# # # #
# Part 2 # # Part 2 #
# # # #
######################################### #########################################
# Part 2 was not possible using either list or deque.
# I tested various calculations to see if there was a
# pattern but i couldn't find one.
# I started using simple recursion in hopes that
# would speed it up. That was not the case.
# I ended up splitting the function in two and the part
# that returns a value from the rules, would be stored
# in a dict where the number and the current blink count
# would be the key.
# If a number+blink combo was already in the dict, it
# would use the already calculated result, instead
# of calculating it again.
# I tested using functools.cache on the rules() function
# but that gave the same compute time.
def rule2(number):
num_str = str(number)
middle = len(num_str) // 2
return [str(int(num_str[:middle])), str(int(num_str[middle:]))]
def genNewNumbers(start,end):
if end == 0:
return 1
end -= 1
if (start,end) not in values:
values[(start,end)] = rules(start,end)
result = values[(start,end)]
return result
def rules(start,end):
if start == '0':
result = genNewNumbers('1',end)
else:
if len(start) % 2 == 0:
x = rule2(start)
result = 0
result += genNewNumbers(x[0],end)
result += genNewNumbers(x[1],end)
else:
result = genNewNumbers(str(int(start)*2024),end)
return result
values = {}
def part2(input_f): def part2(input_f):
dq = [] numbers = []
with open(input_f) as file: with open(input_f) as file:
dq = deque(file.readline().strip().split(' ')) numbers = file.readline().strip().split(' ')
new_inst = deque([])
for r in range(75): result = 0
i = 0 for i in numbers:
while_time = time.time() result += genNewNumbers(i,75)
return result
while i < len(dq):
if dq[i] == 0:
# Rule 1
new_inst.append(1)
else:
# Rule 2
if len(str(dq[i])) % 2 == 0:
x = rule2(dq[i])
new_inst.append(x[0])
new_inst.append(x[1])
else:
# Rule 3
new_inst.append(int(dq[i]) * 2024)
i += 1
dq = new_inst
new_inst = deque([])
print(r,len(dq),"--- %s seconds ---" % (time.time() - while_time))
#print()
print(len(dq))
start_time = time.time() start_time = time.time()
part2(input_f) print('Part 2:',part2(input_f), '\t(cache)\t', round((time.time() - start_time)*1000), 'ms')
print("--- %s seconds ---" % (time.time() - start_time))

View File

@ -12,6 +12,7 @@
|~~..--. _____ | |* /~\ '.| | - / .'| 8 ** |~~..--. _____ | |* /~\ '.| | - / .'| 8 **
'---' ||[][]_\-| |~/ * \ :| | *..' | 9 ** '---' ||[][]_\-| |~/ * \ :| | *..' | 9 **
|------- | | /\ .'| |'''~~~~~| 10 ** |------- | | /\ .'| |'''~~~~~| 10 **
|.......|| |/\ ..' | | . | 11 **
## 2023 ## 2023