Day 5: Cafeteria
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465


Python
Not too bad though part2 could become difficult if you don’t realize the simple method to merge overlapping intervals.
see code
# takes a list of (start, end) ranges and merges overlapping ones def merge_overlapping_ranges(ranges: list[tuple[int, int]]) -> list[tuple[int, int]]: # sort ranges by start so that overlaps are adjacent ranges.sort(key=lambda r: r[0]) merged_ranges = [] # keep track of a current range that could be merged into curr_start, curr_end = ranges[0] for start, end in ranges: if curr_start <= start <= curr_end: # overlap, extend current range curr_end = max(curr_end, end) else: # no overlap, save current range and record the new one merged_ranges.append((curr_start, curr_end)) curr_start, curr_end = start, end # finally, don't forget to add the last range that's being tracked merged_ranges.append((curr_start, curr_end)) return merged_ranges def part1(data: str): # split input freshness_data, ingredients_data = data.split("\n\n") # parse data freshness_ranges = [tuple(map(int, f.split('-'))) for f in freshness_data.splitlines()] freshness_ranges = merge_overlapping_ranges(freshness_ranges) # optimization: merge overlapping ranges ingredients = [int(i) for i in ingredients_data.splitlines()] # checks if an ingredient is fresh # this could've been done with binary search, but linear search is simpler and fast enough def is_fresh(ingredient: int) -> bool: for start, end in freshness_ranges: if start <= ingredient <= end: # found return True if start > ingredient: # quit early since we are past any range that could've contained the ingredient return False return False # count all fresh ingredients return sum(is_fresh(i) for i in ingredients) def part2(data: str): # split input freshness_data, _ = data.split("\n\n") # parse data freshness_ranges = [tuple(map(int, f.split('-'))) for f in freshness_data.splitlines()] freshness_ranges = merge_overlapping_ranges(freshness_ranges) # merge overlapping ranges # return total count of fresh ingredients # we add +1 because both start and end are inclusive return sum(end - start + 1 for start, end in freshness_ranges) sample = """3-5 10-14 16-20 12-18 1 5 8 11 17 32""" assert part1(sample) == 3 assert part2(sample) == 14