Problem p02792 (python)

Fixed submission:
n = int(input())

digits = 1
base = 10
for i in range(0, 20):
    if n < 10 ** i:
        digits = i
        break

smallest_digit = n % 10
largest_digit = n // (10 ** (digits - 1)) % 10
mid_digit_pattern = (n - largest_digit * (10 ** (digits - 1))) // 10 + 1

def count_pattern(a, b, dig):
    if dig == 1 and a != b:
        return 0
    elif dig == 1:
        return 1
    elif dig == digits:
        if a > largest_digit:
            return 0
        elif a < largest_digit:
            return 10 ** (dig - 2)
        elif b <= smallest_digit:
            return mid_digit_pattern
        elif b > smallest_digit:
            return mid_digit_pattern - 1
        else:
            assert False, "Can't reach here"
    else:
        return 10 ** (dig - 2)

result = 0
if digits == 1:
    result = n
else:
    counts = {}
    for i in range(1, 10):
        for j in range(1, 10):
            state = (i, j)
            counts[state] = sum([count_pattern(i, j, d) for d in range(1, digits + 1)])

    for state in counts.keys():
        result += counts[state] * counts[tuple(reversed(state))]

print(result)

Buggy submission (verdict: Runtime Error):
n = int(input())

digits = 1
base = 10
for i in range(0, 20):
    if n < 10 ** i:
        digits = i
        break

smallest_digit = n % 10
largest_digit = n // (10 ** (digits - 1)) % 10
mid_digit_pattern = (n - largest_digit * (10 ** (digits - 1))) // 10 + 1

def count_pattern(a, b, dig):
    if dig == 1 and a != b:
        return 0
    elif dig == 1:
        return 1
    elif dig == digits:
        if a > largest_digit:
            return 0
        elif a < largest_digit:
            return 10 ** (dig - 2)
        elif b <= smallest_digit:
            return mid_digit_pattern
        elif b > smallest_digit:
            return mid_digit_pattern - 1
        else:
            assert False, "Can't reach here"
    else:
        return 10 ** (dig - 2)

result = 0
if digits == 1:
    result = n
else:
    counts = {}
    for i in range(1, 10):
        for j in range(1, 10):
            state = (i, j)
            counts[state] = sum([count_pattern(*state, d) for d in range(1, digits + 1)])

    for state in counts.keys():
        result += counts[state] * counts[tuple(reversed(state))]

print(result)

Buggy submission (verdict: Runtime Error):
n = int(input())

digits = 1
base = 10
for i in range(0, 20):
    if n < 10 ** i:
        digits = i
        break

smallest_digit = n % 10
largest_digit = n // (10 ** (digits - 1)) % 10
mid_digit_pattern = (n - largest_digit * (10 ** (digits - 1))) // 10 + 1

def count_pattern(a, b, dig):
    if dig == 1 and a != b:
        return 0
    elif dig == 1:
        return 1
    elif dig == digits:
        if a > largest_digit:
            return 0
        elif a < largest_digit:
            return 10 ** (dig - 2)
        elif b <= smallest_digit:
            return mid_digit_pattern
        elif b > smallest_digit:
            return mid_digit_pattern - 1
        else:
            assert False, "Can't reach here"
    else:
        return 10 ** (dig - 2)

if digits == 1:
    print(n)
else:
    counts = {}
    for i in range(1, 10):
        for j in range(1, 10):
            state = (i, j)
            counts[state] = sum([count_pattern(*state, d) for d in range(1, digits + 1)])

    result = 0
    for state in counts.keys():
        result += counts[state] * counts[tuple(reversed(state))]
    print(result)

Buggy submission (verdict: Runtime Error):
from functools import reduce

n = int(input())

digits = 1
base = 10
for i in range(0, 20):
    if n < 10 ** i:
        digits = i
        break

smallest_digit = n % 10
largest_digit = n // (10 ** (digits - 1)) % 10
mid_digit_pattern = (n - largest_digit * (10 ** (digits - 1))) // 10 + 1

def count_pattern(a, b, dig):
    if dig == 1 and a != b:
        return 0
    elif dig == 1:
        return 1
    elif dig == digits:
        if a > largest_digit:
            return 0
        elif a < largest_digit:
            return 10 ** (dig - 2)
        elif b <= smallest_digit:
            return mid_digit_pattern
        elif b > smallest_digit:
            return mid_digit_pattern - 1
        else:
            assert False, "Can't reach here"
    else:
        return 10 ** (dig - 2)

if digits == 1:
    print(n)
else:
    counts = {}
    for i in range(1, 10):
        for j in range(1, 10):
            state = (i, j)
            counts[state] = sum([count_pattern(*state, d) for d in range(1, digits + 1)])

    result = 0
    for state in counts.keys():
        result += counts[state] * counts[tuple(reversed(state))]
    print(result)

Buggy submission (verdict: Runtime Error):
from functools import reduce
from itertools import product

n = int(input())

digits = 1
base = 10
for i in range(0, 7):
    if n < 10 ** i:
        digits = i
        break

smallest_digit = n % 10
largest_digit = n // (10 ** (digits - 1)) % 10
mid_digit_pattern = (n - largest_digit * (10 ** (digits - 1))) // 10 + 1

def count_pattern(a, b, dig):
    if dig == 1 and a != b:
        return 0
    elif dig == 1:
        return 1
    elif dig == digits:
        if a > largest_digit:
            return 0
        elif a < largest_digit:
            return 10 ** (dig - 2)
        elif b <= smallest_digit:
            return mid_digit_pattern
        elif b > smallest_digit:
            return mid_digit_pattern - 1
        else:
            assert False, "Can't reach here"
    else:
        return 10 ** (dig - 2)

if digits == 1:
    print(n)
else:
    counts = {}
    for state in product(range(1, 10), range(1, 10)):
        counts[state] = sum([count_pattern(*state, d) for d in range(1, digits + 1)])

    result = 0
    for state in counts.keys():
        result += counts[state] * counts[tuple(reversed(state))]
    print(result)