feat: Day 4 and 5 of '25
This commit is contained in:
parent
f0032ec222
commit
66b413afd9
81
25/5/main.py
Normal file
81
25/5/main.py
Normal file
@ -0,0 +1,81 @@
|
||||
'''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()
|
||||
34
25/5/test_main.py
Normal file
34
25/5/test_main.py
Normal file
@ -0,0 +1,34 @@
|
||||
import pytest
|
||||
|
||||
from main import check_fresh, part1, part2
|
||||
|
||||
test_ranges = [(3, 5), (10, 14), (16, 20), (12, 18)]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('given, id_ranges, expected',
|
||||
[
|
||||
(1, test_ranges, False),
|
||||
(5, test_ranges, True),
|
||||
(8, test_ranges, False),
|
||||
(11, test_ranges, True),
|
||||
(17, test_ranges, True),
|
||||
(32, test_ranges, False)
|
||||
])
|
||||
def test_fresh_checker(given, id_ranges, expected):
|
||||
assert check_fresh(id_ranges, given) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('ids, id_ranges, expected',
|
||||
[
|
||||
([1,5,8,11,17,32], test_ranges, 3)
|
||||
])
|
||||
def test_part1(ids, id_ranges, expected):
|
||||
assert part1(id_ranges, ids) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('id_ranges, expected',
|
||||
[
|
||||
(test_ranges, 14),
|
||||
])
|
||||
def test_part2(id_ranges, expected):
|
||||
assert part2(id_ranges) == expected
|
||||
Loading…
x
Reference in New Issue
Block a user