diff --git a/day4/README.md b/day4/README.md index 552865b..fe17287 100644 --- a/day4/README.md +++ b/day4/README.md @@ -54,8 +54,26 @@ numbers. Visually, these pairs of section assignments look like this: ``` Some pairs have noticed that one of their assignments **fully contains** the other. For example, `2-8` fully contains -`3-7`, and `6-6` is fully contained by `4-6`. In pairs where one assignment fully contains the other, one Elf in the pair +`3-7`, and `6-6` is fully contained by `4-6`. In pairs where one assignment fully contains the other, one Elf in the +pair would be exclusively cleaning sections their partner will already be cleaning, so these seem like the most in need of reconsideration. In this example, there are **2** such pairs. -**In how many assignment pairs does one range fully contain the other?** \ No newline at end of file +**In how many assignment pairs does one range fully contain the other?** + +## Part Two + +It seems like there is still quite a bit of duplicate work planned. Instead, the Elves would like to know the number of +pairs that **overlap at all**. + +In the above example, the first two pairs (`2-4,6-8` and `2-3,4-5`) don't overlap, while the remaining four +pairs (`5-7,7-9`, `2-8,3-7`, `6-6,4-6`, and `2-6,4-8`) do overlap: + +- `5-7,7-9` overlaps in a single section, `7`. +- `2-8,3-7` overlaps all the sections `3` through `7`. +- `6-6,4-6` overlaps in a single section, `6`. +- `2-6,4-8` overlaps in sections `4`, `5`, and `6`. + +So, in this example, the number of overlapping assignment pairs is `4`. + +**In how many assignment pairs do the ranges overlap?** \ No newline at end of file diff --git a/day4/main.py b/day4/main.py index f5ea27c..a0401a1 100644 --- a/day4/main.py +++ b/day4/main.py @@ -1,3 +1,5 @@ +from typing import Callable, Iterable + from common.file import read_data test_dataset = [ @@ -11,20 +13,22 @@ test_dataset = [ def find_overlapping_assignments_1(data: list[str]) -> int: - # iterate over the data, for each line - counter = 0 - for line in data: - # split the ',' - a, b = line.strip().split(",") - start_a, end_a = [int(x) for x in a.split("-")] - int_a = range(start_a, end_a + 1) - start_b, end_b = [int(x) for x in b.split("-")] - int_b = range(start_b, end_b + 1) - # if 1 interval in the other increment the counter - if all(x in int_b for x in int_a) or all(x in int_a for x in int_b): - counter += 1 - # return the counter - return counter + return sum(process(line, all) for line in data) + + +def find_overlapping_assignments_2(data: list[str]) -> int: + return sum(process(line, any) for line in data) + + +def process(line: str, func: Callable[[Iterable], bool]) -> int: + a, b = line.strip().split(",") + + start_a, end_a = [int(x) for x in a.split("-")] + int_a = range(start_a, end_a + 1) + start_b, end_b = [int(x) for x in b.split("-")] + int_b = range(start_b, end_b + 1) + + return int(func(x in int_b for x in int_a) or func(x in int_a for x in int_b)) if __name__ == "__main__": @@ -32,6 +36,6 @@ if __name__ == "__main__": res = find_overlapping_assignments_1(dataset) assert res == 2, f"{res} is not the right value" - # - # res = priority_shared_items_sum_2(dataset) - # assert res == 70, f"{res} is not the right value" + + res = find_overlapping_assignments_2(dataset) + assert res == 4, f"{res} is not the right value"