Solve #2: gift shop.
This commit is contained in:
1
02-gift-shop/input01.txt
Normal file
1
02-gift-shop/input01.txt
Normal file
@@ -0,0 +1 @@
|
||||
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124
|
||||
77
02-gift-shop/solve.py
Executable file
77
02-gift-shop/solve.py
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
def magnitude(x : int) -> int:
|
||||
assert x >= 0
|
||||
return len(str(x))
|
||||
|
||||
def delta(order : int) -> int:
|
||||
return 10**order + 1
|
||||
|
||||
def sum_1_to_excl(x : int) -> int:
|
||||
return x * (x - 1) // 2
|
||||
|
||||
def sum_1_to_incl(x : int) -> int:
|
||||
return x * (x + 1) // 2
|
||||
|
||||
# incl. both bounds
|
||||
def sum_from_to_incl(lo : int, hi : int) -> int:
|
||||
if lo > hi:
|
||||
return 0
|
||||
|
||||
return sum_1_to_incl(hi) - sum_1_to_excl(lo)
|
||||
|
||||
def div2(x : int) -> Optional[int]:
|
||||
if x % 2:
|
||||
return None
|
||||
else:
|
||||
return x // 2
|
||||
|
||||
# inclusive both bounds
|
||||
def sum_invalid_ids(lo : int, hi : int) -> int:
|
||||
total = 0
|
||||
|
||||
while True:
|
||||
magnitude_lo = magnitude(lo)
|
||||
order_lo = div2(magnitude_lo)
|
||||
if order_lo is None:
|
||||
# no invalid IDs in that order of magnitude
|
||||
lo = 10**magnitude_lo
|
||||
continue
|
||||
|
||||
magnitude_hi = magnitude(hi)
|
||||
d = delta(order_lo)
|
||||
|
||||
if magnitude_lo > magnitude_hi:
|
||||
# this can happen with odd magnitude_hi
|
||||
break
|
||||
|
||||
elif magnitude_lo == magnitude_hi:
|
||||
assert lo <= hi, f"{lo} <= {hi}"
|
||||
total += d * sum_from_to_incl((lo-1)//d + 1, hi // d)
|
||||
break
|
||||
|
||||
assert magnitude_lo < magnitude_hi
|
||||
surrogate_hi = 10**magnitude_lo - 1
|
||||
assert lo <= surrogate_hi, f"{lo} <= {surrogate_hi}"
|
||||
total += d * sum_from_to_incl((lo-1)//d + 1, surrogate_hi // d)
|
||||
lo = surrogate_hi + 1
|
||||
|
||||
return total
|
||||
|
||||
if __name__ == '__main__':
|
||||
ranges = [
|
||||
(int(lo_s), int(hi_s))
|
||||
for lo_s, hi_s in (
|
||||
rng.split('-')
|
||||
for rng in sys.stdin.read().strip().split(',')
|
||||
)
|
||||
]
|
||||
|
||||
total = 0
|
||||
for lo, hi in ranges:
|
||||
total += sum_invalid_ids(lo, hi)
|
||||
|
||||
print(total)
|
||||
Reference in New Issue
Block a user