Day 5
This commit is contained in:
parent
aa7e16a7f7
commit
2fa934b2d0
129
day05.py
Normal file
129
day05.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# https://adventofcode.com/2025/day/5
|
||||||
|
|
||||||
|
f = open("day05input.txt", "r")
|
||||||
|
#f = open("testinput.txt", "r")
|
||||||
|
d = [l.strip() for l in f.readlines()]
|
||||||
|
|
||||||
|
|
||||||
|
# prepare data
|
||||||
|
if "" in d:
|
||||||
|
i = d.index("")
|
||||||
|
Ranges = [[int(r.split("-")[0]), int(r.split("-")[1])] for r in d[:i]]
|
||||||
|
IDs = list(map(int, d[i+1:]))
|
||||||
|
else:
|
||||||
|
Ranges = [[int(r.split("-")[0]), int(r.split("-")[1])] for r in d]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part1(ranges: list[list[int, int]], ids: list[int]) -> int:
|
||||||
|
for r in ranges:
|
||||||
|
assert int(r[0]) <= int(r[1])
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
# loop over IDs
|
||||||
|
for _id in ids:
|
||||||
|
id_counter = 0
|
||||||
|
|
||||||
|
# loop over ranges
|
||||||
|
for r in ranges:
|
||||||
|
if r[0] <= _id <= r[1]:
|
||||||
|
total += 1
|
||||||
|
break
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def part2(ranges: list[list[int, int]]) -> int:
|
||||||
|
for r in ranges:
|
||||||
|
assert int(r[0]) <= int(r[1])
|
||||||
|
|
||||||
|
distinct_ranges = []
|
||||||
|
|
||||||
|
|
||||||
|
# integrates current range with current list of distinct ranges
|
||||||
|
# returns true if a change was made to distinct_ranges
|
||||||
|
def compare(c_range: list[int, int]) -> bool:
|
||||||
|
r_min, r_max = c_range
|
||||||
|
|
||||||
|
# checks subcase
|
||||||
|
def subcase():
|
||||||
|
# subcase a: it's the last distinct range or the range ends before the next distinct range starts
|
||||||
|
if i == len(distinct_ranges) - 1 or r_max < distinct_ranges[i + 1][0]:
|
||||||
|
d_range[1] = r_max
|
||||||
|
# subcase b: range ends inside next distinct range
|
||||||
|
elif distinct_ranges[i + 1][0] <= r_max <= distinct_ranges[i + 1][1]:
|
||||||
|
d_range[1] = distinct_ranges[i + 1][1]
|
||||||
|
distinct_ranges.pop(i + 1)
|
||||||
|
# subcase c: range stretches beyond the end of the next distinct range
|
||||||
|
# I'll ignore this case b/c I think it doesn't occur
|
||||||
|
else:
|
||||||
|
raise Exception("Shit, I missed a subcase!")
|
||||||
|
|
||||||
|
|
||||||
|
# loop over distinct ranges
|
||||||
|
for i in range(len(distinct_ranges)):
|
||||||
|
d_range = distinct_ranges[i]
|
||||||
|
|
||||||
|
# case 1: range sits completely outside current distinct range
|
||||||
|
if r_max < d_range[0] or d_range[1] < r_min:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# case 2: range sits inside the current distinct range
|
||||||
|
elif d_range[0] <= r_min <= r_max <= d_range[1]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# case 3: range spans from outside into current distant range, but not beyond
|
||||||
|
elif r_min < d_range[0] <= r_max <= d_range[1]:
|
||||||
|
d_range[0] = r_min
|
||||||
|
return True
|
||||||
|
|
||||||
|
# case 4: range spans from inside the current distance range beyond its end
|
||||||
|
elif d_range[0] <= r_min <= d_range[1] < r_max:
|
||||||
|
subcase()
|
||||||
|
return True
|
||||||
|
|
||||||
|
# case 5: range completely envelops current distant range
|
||||||
|
elif r_min < d_range[0] < d_range[1] < r_max:
|
||||||
|
d_range[0] = r_min
|
||||||
|
subcase()
|
||||||
|
return True
|
||||||
|
|
||||||
|
# case 6: I missed a case
|
||||||
|
else:
|
||||||
|
raise Exception("Shit, I missed a case!")
|
||||||
|
|
||||||
|
distinct_ranges.append(c_range)
|
||||||
|
distinct_ranges.sort(key=lambda a: a[0])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# compute ranges with no overlaps
|
||||||
|
for r in ranges:
|
||||||
|
# print(distinct_ranges)
|
||||||
|
|
||||||
|
# no distinct ranges yet?
|
||||||
|
if len(distinct_ranges) == 0:
|
||||||
|
distinct_ranges.append(r)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# compare new range to all distinct ranges computed so far
|
||||||
|
# repeat until no changes happened
|
||||||
|
while True:
|
||||||
|
has_changed = compare(r)
|
||||||
|
|
||||||
|
# make sure distinct ranges never overlap
|
||||||
|
assert all([distinct_ranges[j+1][0] - distinct_ranges[j][1] > 0 for j in range (len(distinct_ranges) - 1)])
|
||||||
|
|
||||||
|
if not has_changed:
|
||||||
|
break
|
||||||
|
|
||||||
|
return sum([r[1] - r[0] + 1 for r in distinct_ranges])
|
||||||
|
|
||||||
|
|
||||||
|
#print(part1(Ranges, IDs))
|
||||||
|
print(part2(Ranges))
|
||||||
1193
day05input.txt
Normal file
1193
day05input.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user