diff --git a/02-gift-shop/input01.txt b/02-gift-shop/input01.txt new file mode 100644 index 0000000..a3f22ef --- /dev/null +++ b/02-gift-shop/input01.txt @@ -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 diff --git a/02-gift-shop/solve.py b/02-gift-shop/solve.py new file mode 100755 index 0000000..8e2456c --- /dev/null +++ b/02-gift-shop/solve.py @@ -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)