82 lines
1.8 KiB
Python
82 lines
1.8 KiB
Python
'''AoC Day 5'''
|
|
|
|
import operator
|
|
|
|
def deoverlap(ranges: []) -> []:
|
|
'''Reduce a list of ranges that may overlap'''
|
|
new_ranges = []
|
|
|
|
ranges.sort(key=operator.itemgetter(0))
|
|
|
|
for r in ranges:
|
|
found_overlap = False
|
|
for index, nr in enumerate(new_ranges):
|
|
if r[0] <= nr[1] and nr[0] <= r[1]:
|
|
start = min(r[0], nr[0])
|
|
end = max(r[1], nr[1])
|
|
new_ranges[index] = (start, end)
|
|
found_overlap = True
|
|
|
|
if found_overlap is False:
|
|
new_ranges.append(r)
|
|
else:
|
|
found_overlap = False
|
|
|
|
return new_ranges
|
|
|
|
|
|
def check_fresh(ranges: [], id: int) -> bool:
|
|
'''Return if a given id is found in any given ranges'''
|
|
for r in ranges:
|
|
if id in range(r[0], r[1] + 1):
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def part1(ranges: [], ids: []) -> int:
|
|
'''Part 1, all currently fresh ids'''
|
|
total = 0
|
|
|
|
for id in ids:
|
|
if check_fresh(ranges, id):
|
|
total += 1
|
|
|
|
return total
|
|
|
|
|
|
def part2(ranges: []) -> int:
|
|
'''Part 2, all possible fresh ids'''
|
|
ranges = deoverlap(ranges)
|
|
|
|
fresh_ids = 0
|
|
|
|
for r in ranges:
|
|
fresh_ids += len(range(r[0], r[1] + 1))
|
|
|
|
return fresh_ids
|
|
|
|
|
|
def main():
|
|
'''Entrypoint'''
|
|
with open('input.txt', encoding='utf-8') as fh:
|
|
ranges = []
|
|
ids = []
|
|
|
|
for line in fh:
|
|
if '-' in line:
|
|
id_range = line.strip().split('-')
|
|
ranges.append((int(id_range[0]), int(id_range[1])))
|
|
elif line.strip() != '':
|
|
ids.append(int(line.strip()))
|
|
|
|
freshies = part1(ranges, ids)
|
|
print(f'Part1: {freshies}')
|
|
|
|
total_fresh = part2(ranges)
|
|
|
|
print(f'Part2: {total_fresh}')
|
|
|
|
if __name__ == "__main__":
|
|
main()
|