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