134 lines
3.7 KiB
Python
134 lines
3.7 KiB
Python
#!/usr/bin/env python
|
|
# coding: utf-8
|
|
|
|
# # Puzzle 2 of AoC 2025
|
|
# Author: Victoria Ramírez López
|
|
#
|
|
# Date: Dec 2, 2025
|
|
|
|
|
|
# In[18]:
|
|
|
|
def find_invalid_ids(id_range=''):
|
|
# This function finds the invalid ids within the specified range (part 1)
|
|
# input: id_range = String
|
|
# output: invalid_ids = int []
|
|
|
|
invalid_ids = []
|
|
invalid_id = []
|
|
|
|
# Extract the upper and lower bounds of the range
|
|
lb = int(id_range.split('-')[0])
|
|
ub = int(id_range.split('-')[1]) + 1
|
|
|
|
# Generate the series of product ids withing the range
|
|
product_ids = range(lb,ub)
|
|
|
|
# Find invalid ids
|
|
for id in product_ids:
|
|
id_string = str(id) # Convert each product id to string
|
|
|
|
if len(id_string) % 2 == 0:
|
|
middle_point = len(id_string) // 2 # Find where to split the product id in 2
|
|
|
|
# Compare the two halves of the id to determine if the id is invalid
|
|
first_half = id_string[0:middle_point]
|
|
second_half = id_string[middle_point:]
|
|
|
|
if first_half == second_half: # If the two halves are equal, the id is invalid
|
|
invalid_id = int(id_string)
|
|
invalid_ids.append(invalid_id)
|
|
|
|
return invalid_ids
|
|
|
|
|
|
# In[33]:
|
|
|
|
def chop_product_id(id):
|
|
# This function chops a product id into chunks of equal sizes
|
|
# input: id = int
|
|
# output: chopped_id = [[]]
|
|
|
|
id_string = str(id)
|
|
chunks = []
|
|
chopped_id = []
|
|
|
|
# Find divisors to split the id into equal-sized chunks
|
|
# (aka: how many ways to split the id into equal-sized chunks are there?)
|
|
for divisor in range(2,len(id_string) + 1):
|
|
if len(id_string) % divisor == 0:
|
|
chunks = []
|
|
chunk_size = len(id_string) // divisor # Determine how big a chunk would be
|
|
|
|
for i in range(1,len(id_string)+1,chunk_size): # Chop the id
|
|
chunk = id_string[i-1:(i-1 + chunk_size)]
|
|
chunks.append(chunk)
|
|
|
|
chopped_id.append(chunks)
|
|
|
|
return chopped_id
|
|
|
|
|
|
# In[49]:
|
|
|
|
# Read product ID ranges file
|
|
|
|
import csv
|
|
input_file = open('../rust/inputs/02.txt', mode ='r') # Open in 'read only' mode
|
|
id_ranges_csv = csv.reader(input_file)
|
|
id_ranges_list = list(id_ranges_csv)
|
|
|
|
|
|
# In[51]:
|
|
|
|
def find_all_invalid_ids(id_range=''):
|
|
# This function finds all the invalid ids within the specified range (part 2)
|
|
# input: id_range = String
|
|
# output: invalid_ids = int [[]]
|
|
|
|
invalid_ids = []
|
|
invalid_id = []
|
|
|
|
# Extract the upper and lower bounds of the range
|
|
lb = int(id_range.split('-')[0])
|
|
ub = int(id_range.split('-')[1]) + 1
|
|
|
|
# Generate the series of product ids withing the range
|
|
product_ids = range(lb,ub)
|
|
|
|
# Find invalid ids
|
|
for id in product_ids:
|
|
id_string = str(id) # Convert each product id to string
|
|
|
|
chopped_ids = chop_product_id(id) # Chop each product id into equal-sized pieces
|
|
|
|
# Identify ids with a repeating pattern
|
|
for list in chopped_ids:
|
|
chunks_set = set(list) # Convert each group of equal-sized chunks into a set
|
|
|
|
if len(chunks_set) == 1: # If the resulting set has only 1 element, the id is invalid
|
|
invalid_id = int(id_string)
|
|
invalid_ids.append(invalid_id)
|
|
break
|
|
|
|
return(invalid_ids)
|
|
|
|
|
|
# In[52]:
|
|
|
|
# Get invalid ids and calculate answer
|
|
|
|
invalid_ids = []
|
|
id_ranges = []
|
|
|
|
for id_range in id_ranges_list[0]:
|
|
# invalid_ids_range = find_invalid_ids(id_range) # For part 1 answer
|
|
invalid_ids_range = find_all_invalid_ids(id_range) # For part 2 answer
|
|
invalid_ids.append(invalid_ids_range[:])
|
|
|
|
sum_invalid_ids = sum(sum(invalid_ids,[]))
|
|
# print(invalid_ids)
|
|
print(sum_invalid_ids)
|
|
|
|
|