solve Day05 Part2 in Python

This commit is contained in:
WieErWill 2023-12-06 19:08:52 +01:00
parent 39280b7906
commit 53818e5bd2
2 changed files with 57 additions and 57 deletions

View File

@ -1,61 +1,67 @@
import os import os
import gc import gc
from itertools import groupby
def free_up_memory(): def free_up_memory():
"""Explicitly frees up memory.""" """Explicitly frees up memory."""
gc.collect() gc.collect()
def parse_ranges(line): def parse_input(file_path):
"""Parses a line containing seed ranges.""" """Parses the input file into seeds and categories."""
numbers = list(map(int, line.split())) with open(file_path) as file:
return [(numbers[i], numbers[i + 1]) for i in range(0, len(numbers), 2)] lines = file.read().splitlines()
def map_single_seed_through_category(seed, category_map): groups = [tuple(group) for not_empty, group in groupby(lines, bool) if not_empty]
"""Maps a single seed through a category based on the mapping.""" seeds, *categories = groups
print(f"map seed {seed} in category map") seeds_ranges = tuple(map(int, seeds[0].split()[1:]))
for source_start, (dest_start, range_length) in category_map.items(): seeds_numbers = [
if source_start <= seed < source_start + range_length: (seeds_ranges[i], seeds_ranges[i] + seeds_ranges[i + 1])
return dest_start + (seed - source_start) for i in range(0, len(seeds_ranges), 2)
return seed ]
return seeds_numbers, categories
def process_category(file, ranges): def process_categories(seeds_numbers, categories):
"""Processes seed ranges through a single category based on the file lines.""" """Processes the seed ranges through all categories."""
category_map = {} for category in categories:
for i, line in file: ranges = [tuple(map(int, numbers.split())) for numbers in category[1:]]
line = line.strip()
if not line or ':' in line: # End of the current category map
break
dest_start, source_start, range_length = map(int, line.split())
category_map[source_start] = (dest_start, range_length)
print(f"parsed line {i} in file")
# Process each seed through the category map sources = []
mapped_seeds = set() while seeds_numbers:
for start, length in ranges: start, end = seeds_numbers.pop()
print(f"process range {start} with length {length}") for destination, source, length in ranges:
for i in range(length): overlap_start = max(start, source)
seed = start + i overlap_end = min(end, source + length)
mapped_seed = map_single_seed_through_category(seed, category_map) if overlap_start < overlap_end:
mapped_seeds.add(mapped_seed) sources.append(
(
return mapped_seeds overlap_start - source + destination,
overlap_end - source + destination,
def process_file(file_path): )
"""Processes the file to find the lowest location number for the seed ranges.""" )
try: if overlap_start > start:
with open(file_path, 'r') as file: seeds_numbers.append((start, overlap_start))
ranges = parse_ranges(file.readline().split(':')[1]) if end > overlap_end:
seeds_numbers.append((overlap_end, end))
while True:
line = file.readline()
if not line: # End of file
break break
if ':' in line: # Start of a new category map else:
ranges = {(seed, 1) for seed in process_category(file, ranges)} sources.append((start, end))
lowest_location = min(ranges)[0] seeds_numbers = sources
return seeds_numbers
return lowest_location def find_lowest_location(file_path, is_test=False, expected_result=None):
"""Finds the lowest location number from the input file."""
try:
seeds_numbers, categories = parse_input(file_path)
seeds_numbers = process_categories(seeds_numbers, categories)
lowest_location = min(seeds_numbers)[0]
if is_test:
assert lowest_location == expected_result, f"Test failed, expected {expected_result} but got {lowest_location}"
print("Test passed.")
else:
print(f"Lowest location from {file_path}: {lowest_location}")
return lowest_location
except FileNotFoundError: except FileNotFoundError:
print(f"Error: File '{file_path}' not found.") print(f"Error: File '{file_path}' not found.")
@ -66,21 +72,16 @@ def test():
"""Run tests using the test.txt file.""" """Run tests using the test.txt file."""
print("Starting test") print("Starting test")
expected_result = 46 # Updated expected result for the new puzzle expected_result = 46 # Updated expected result for the new puzzle
result = process_file('../test.txt') find_lowest_location('../test.txt', is_test=True, expected_result=expected_result)
assert result == expected_result, f"Test failed, expected 46 but got {result}"
print(f"Test passed: {result}")
def main(): def main():
"""Main function to process the input file and display results.""" """Main function to process the input file and display results."""
try: try:
# Run tests first
test() test()
free_up_memory() # Free memory after testing free_up_memory() # Free memory after testing
# Process actual input
print("Starting input.txt") print("Starting input.txt")
result = process_file("../input.txt") find_lowest_location("../input.txt")
print(f"Total result from input.txt: {result}")
free_up_memory() free_up_memory()
except Exception as e: except Exception as e:

View File

@ -1,6 +1,5 @@
# Advent of Code 2023 # 🎄 Advent of Code 2023 🎄
## Overview
Welcome to my repository where I share my solutions for the [Advent of Code 2023](https://adventofcode.com/2023). Advent of Code is an annual online event where participants solve a series of programming puzzles released daily from December 1st until December 25th. Each puzzle is a fun and unique challenge designed to test problem-solving skills. Welcome to my repository where I share my solutions for the [Advent of Code 2023](https://adventofcode.com/2023). Advent of Code is an annual online event where participants solve a series of programming puzzles released daily from December 1st until December 25th. Each puzzle is a fun and unique challenge designed to test problem-solving skills.
## Structure ## Structure
@ -16,13 +15,13 @@ Within each folder, you'll find:
- `README.md`: A brief description of the day's problem. - `README.md`: A brief description of the day's problem.
- Source code files: My solution for the day's puzzle, typically in Python or Rust - Source code files: My solution for the day's puzzle, typically in Python or Rust
- `input.txt`: The input data provided for the puzzle. - `input.txt`: The input data provided for the puzzle. (add those yourself as we don't provide those for legal reasons)
- Additional resources or notes if applicable. - Additional resources or notes if applicable.
## My Approach ## My Approach
For Advent of Code 2023, I've decided to primarily use Python due to its readability and the extensive libraries available, which make it an excellent choice for solving diverse and complex problems quickly. In each solution, I focus not only on solving the problem but also on writing clean, efficient, and well-documented code. For Advent of Code 2023, I've decided to primarily use Python due to its readability and the extensive libraries available, which make it an excellent choice for solving diverse and complex problems quickly. In each solution, I focus not only on solving the problem but also on writing clean, efficient, and well-documented code.
## Progress ## 📈 Progress
Here I'll track my progress throughout the event. Here I'll track my progress throughout the event.
I aim to complete each day's puzzle on the same day, but as with any challenge, there might be some delays. I aim to complete each day's puzzle on the same day, but as with any challenge, there might be some delays.
@ -32,7 +31,7 @@ I aim to complete each day's puzzle on the same day, but as with any challenge,
| 02 | ✅ | ✅ | [Day02 README](/Day02/README.md) | | 02 | ✅ | ✅ | [Day02 README](/Day02/README.md) |
| 03 | ✅ | ✅ | [Day03 README](/Day03/README.md) | | 03 | ✅ | ✅ | [Day03 README](/Day03/README.md) |
| 04 | ✅ | ✅ | [Day04 README](/Day04/README.md) | | 04 | ✅ | ✅ | [Day04 README](/Day04/README.md) |
| 05 | ✅ | | [Day05 README](/Day05/README.md) | | 05 | ✅ | | [Day05 README](/Day05/README.md) |
| 06 | ❓ | ❓ | [Day06 README](/Day06/README.md) | | 06 | ❓ | ❓ | [Day06 README](/Day06/README.md) |
| 07 | ❓ | ❓ | [Day07 README](/Day07/README.md) | | 07 | ❓ | ❓ | [Day07 README](/Day07/README.md) |
| 08 | ❓ | ❓ | [Day08 README](/Day08/README.md) | | 08 | ❓ | ❓ | [Day08 README](/Day08/README.md) |