def item_in_range(item, id_range): start = id_range[0] end = id_range[1] return start <= item <= end def squash_ranges(id_ranges): while True: id_ranges_size = len(id_ranges) squash_range = [] squash_range.append(id_ranges[0].copy()) for checker in id_ranges: overlap = False for candidate in squash_range: # Squash if checker min within candidate range or otherway around if item_in_range(checker[0], candidate) or item_in_range(candidate[0], checker): overlap = True candidate[0] = min(checker[0],candidate[0]) candidate[1] = max(checker[1],candidate[1]) if not overlap: squash_range.append(checker.copy()) id_ranges = squash_range.copy() if id_ranges_size == len(id_ranges): # If no changes, break break return id_ranges def read_input(filename): id_ranges = [] for line in open(filename).read().splitlines(): if line == "": return id_ranges id_range = line.split("-") id_ranges.append([int(id_range[0]),int(id_range[1])]) # filename = "day05/my_example_input" # filename = "day05/example_input" # 14 filename = "day05/input" # 358155203664116 id_ranges = read_input(filename) id_ranges = squash_ranges(id_ranges) counter = 0 for id_range in id_ranges: counter += (id_range[1] - id_range[0]) + 1 # ranges are inclusive... print(f"Fresh items: {counter}")