Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from collections import deque
- def parse_data(fp: str) -> tuple[list[tuple[int, int]], list[int]]:
- range_collection = []
- num_collection = []
- with open(fp, "r") as f:
- data = f.read()
- ranges, nums = data.split("\n\n")
- for line in ranges.split("\n"):
- l, r = map(int, line.split("-"))
- range_collection.append((l, r))
- for n in map(int, nums.split("\n")):
- num_collection.append(n)
- return range_collection, num_collection
- def is_fresh(i: int, rngs: list[tuple[int, int]]) -> bool:
- """
- >>> assert is_fresh(1, [range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is False
- >>> assert is_fresh(5, [range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is True
- >>> assert is_fresh(8, [range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is False
- >>> assert is_fresh(11,[range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is True
- >>> assert is_fresh(17,[range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is True
- >>> assert is_fresh(32,[range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) is False
- """
- return any(i in r for r in rngs)
- def count_fresh(nums: list[int], ranges: list[range]) -> int:
- fresh_count = 0
- for i in nums:
- if is_fresh(i, ranges):
- fresh_count += 1
- return fresh_count
- def calculate_all_fresh(rngs: list[range]) -> int:
- """
- >>> assert calculate_all_fresh([range(3, 6), range(10, 15), range(16, 21), range(12, 19)]) == 14
- """
- rngs = sorted(rngs, key=lambda x: x[0])
- d = deque(rngs)
- fresh_count = 0
- min_val, max_val = 0, 0
- while d:
- l = d.popleft()
- min_val = l.start
- max_val = l.stop
- while d:
- r = d.popleft()
- if r.start > max_val:
- fresh_count += max_val - min_val
- d.appendleft(r)
- break
- elif (r.start < max_val) and (
- r.stop < max_val
- ): # next range is inclusive in prior ranges
- continue
- else: # next range min in prior range, max val extends range
- max_val = r.stop
- fresh_count += max_val - min_val # capture final range
- return fresh_count
- def convert_to_ranges(rngs: list[tuple[int, int]]) -> list[range]:
- return [range(a, b + 1) for a, b in rngs]
- def part_a():
- """
- >>> fp = "day05a.txt"
- >>> rngs, vegetables = parse_data(fp)
- >>> ranges = convert_to_ranges(rngs)
- >>> count = count_fresh(vegetables, ranges)
- >>> assert count == 3
- """
- fp = "day05.txt"
- rngs, vegetables = parse_data(fp)
- ranges = convert_to_ranges(rngs)
- count = count_fresh(vegetables, ranges)
- print(count)
- def part_b():
- """
- >>> fp = "day05a.txt"
- >>> rngs, _ = parse_data(fp)
- >>> rngs = convert_to_ranges(rngs)
- >>> assert calculate_all_fresh(rngs) == 14
- """
- fp = "day05.txt"
- rngs, _ = parse_data(fp)
- rngs = convert_to_ranges(rngs)
- all_fresh = calculate_all_fresh(rngs)
- print(all_fresh)
- if __name__ == "__main__":
- part_a()
- part_b()
Advertisement
Add Comment
Please, Sign In to add comment