def parse(s): ret = [] for pair in s.split(','): x,y = pair.split('-') ret.append((int(x),int(y))) return ret def solve(input): with open(input) as f: ranges = parse(f.read()) t = 0 for lo,hi in ranges: invalid = list(findinvalid(lo,hi)) #if len(invalid) == 0: # print(lo,hi,invalid) t += sum(invalid) print(t) t2 = 0 for lo,hi in ranges: invalid2 = set(findinvalid2(lo,hi)) t2 += sum(invalid2) print(t2) def findinvalid(lo, hi): assert len(str(hi)) - len(str(lo)) <= 1 assert lo <= hi j = len(str(lo)) // 2 if j < 1: # (1,19) => [11] j = 1 for B in [10**j, 10**(j+1)]: for i in range(lo//B, hi//B+1): if i < B//10: continue if i >= B: break id = i*B + i if lo <= id <= hi: assert(str(i)+str(i) == str(id)), (i,id) #print(lo, hi, i,B,id) yield id def findinvalid2(lo, hi): assert lo <= hi,(lo,hi) if len(str(hi)) != len(str(lo)): assert len(str(hi)) - len(str(lo)) == 1 yield from findinvalid2(lo,10**len(str(lo))-1) yield from findinvalid2(10**(len(str(hi))-1),hi) return N = len(str(hi)) for d in range(1,N): if N%d == 0: B = 10**d BB = 10**(N-d) factor = sum(10**k for k in range(0,N,d)) for i in range(lo//BB, hi//BB+1): if i < B//10: continue if i >= B: break id = i*factor #print(lo,hi,factor,i,id) if lo <= id <= hi: #assert(str(i)*(N//d) == str(id)), (i,id) #print(lo, hi, i,B,id) yield id #solve("sample") solve("input")