Problem p03097 (python)

Fixed submission:
from collections import deque


def i_to_b(n, N):
    A = [0] * N
    for i in range(N):
        A[i] = (n // 2**i) % 2
    return A


def b_to_i(A):
    ret = 0
    for i in range(len(A)):
        ret += i**2*A[i]
    return ret


def rm_bit(n, i):
    return n // (2**(i+1)) * (2**i) + (n % (2**i))


def ins_bit(n, i, b):
    return n // (2**i) * (2**(i+1)) + (n % (2**i)) + b * (2**i)


def solve(N, A, B):
    if N == 1:
        return [A, B]
    idx = -1
    for i in range(N):
        if (A ^ B) & (2**i):
            idx = i
            break
    ra = rm_bit(A, idx)
    rb = rm_bit(B, idx)
    a = list(map(lambda x: ins_bit(x, idx, (A >> idx) & 1), solve(N-1, ra, ra ^ 1)))
    b = list(map(lambda x: ins_bit(x, idx, (B >> idx) & 1), solve(N-1, ra ^ 1, rb)))
    return a + b


def main():
    N, A, B = map(int, input().split())
    binA = i_to_b(A, N)
    binB = i_to_b(B, N)
    if abs(sum(binA) - sum(binB)) % 2 == 0:
        print("NO")
        return
    print("YES")
    print(*solve(N, A, B))


if __name__ == "__main__":
    main()

Buggy submission (verdict: Runtime Error):
def rm_bit(n, i):
    return n // (2**(i+1)) * (2**i) + (n % (2**i))


def ins_bit(n, i, b):
    return n // (2**i) * (2**(i+1)) + (n % (2**i)) + b * (2**i)


def solve(N, A, B):
    if N == 1:
        return [A, B]
    idx = -1
    for i in range(N):
        if (A ^ B) & (2**i):
            idx = i
            break
    ra = rm_bit(A, idx)
    rb = rm_bit(B, idx)
    a = list(map(lambda x: ins_bit(x, idx, (A >> idx) & 1), solve(N-1, ra, ra ^ 1)))
    b = list(map(lambda x: ins_bit(x, idx, (B >> idx) & 1), solve(N-1, ra ^ 1, rb)))
    return a + b


def main():
    N, A, B = map(int, input().split())
    x = A ^ B
    cnt = 0
    for i in range(N):
        cnt += x & (2**i)
    if cnt % 2 == 1:
        print("NO")
    else:
        print("YES")
        print(*solve(N, A, B))


if __name__ == "__main__":
    main()

Buggy submission (verdict: Runtime Error):
from collections import deque


def i_to_b(n, N):
    A = [0] * N
    for i in range(N):
        A[i] = (n // 2**i) % 2
    return A


fact = [1] * 17
for i in range(1, 17):
    fact[i] = fact[i-1] * i


def combination(n, r):
    return fact[n] // fact[r] // fact[n-r]


def main():
    N, A, B = map(int, input().split())
    binA = i_to_b(A, N)
    binB = i_to_b(B, N)
    if abs(sum(binA) - sum(binB)) % 2 == 0:
        print("NO")
        return
    visited = set()
    cnt = [0] * (N+1)
    for i in range(N+1):
        cnt[i] = combination(N, i)
    ans = [-1] * (2**i)
    b = i_to_b((2**N-1)-B, N)
    idx = 2**N - 1
    visited.add(B)
    ans[idx] = B
    cnt[sum(i_to_b(B, N))] -= 1
    for i in range(N):
        if b[i] == 1:
            idx -= 1
            B += 2**i
            visited.add(B)
            ans[idx] = B
            cnt[sum(i_to_b(B, N))] -= 1
    current = A
    idx = 0
    while sum(cnt) > 0:
        visited.add(current)
        ans[idx] = current
        b = i_to_b(current, N)
        c = sum(b)
        cnt[c] -= 1
        idx += 1
        if c >= 1 and cnt[c-1] >= 1:
            for i in range(N):
                if b[i] == 1:
                    nxt = current - 2**i
                    if nxt not in visited:
                        current = nxt
                        break
        else:
            for i in range(N):
                if b[i] == 0:
                    nxt = current + 2**i
                    if nxt not in visited:
                        current = nxt
                        break
    print("YES")
    print(" ".join(map(str, ans)))


if __name__ == "__main__":
    main()