I have written a program for the SPOJ PALIN problem:
A positive integer is called a palindrome if its[decimal representation is the same]from left to right and from right to left. For a given positive integer K of not more than 1000000 digits, write the value of the smallest palindrome larger than K to output. …
My program does not seem to be fast enough (needs to run between 2s - 9s). One way I have thought of is getting rid of the string based math but when I coded that, it started to fail on specific numbers. Is there a way to optimize this code that I am not seeing?
Code:
from math import ceil
def next_palindrome(n):
digits = list(str(n))
length = len(digits)
mid = length / 2
rev = int("".join(digits[::-1]))
if all(d == "9" for d in digits):
return n + 2
if length == 1:
return n + 1
left = digits[: int(mid)]
digits[ceil(mid) :] = left[::-1]
palindrome = int("".join(digits))
if palindrome > n:
return palindrome
if length % 2 != 0:
mid = int(mid)
if digits[mid] == "9":
# return int("".join(digits)) + (11 * (10 * (mid - 1)))
return int("".join(digits)) + int(f"11{'0' * (mid - 1)}")
digits[mid] = f"{int(digits[mid])+1}"
return "".join(digits)
left_d, right_d = left[-1], digits[ceil(mid) :][0]
if left_d == "9" and right_d == "9":
mid = int(mid)
# return int("".join(digits)) + (11 * (10 * (mid - 2)))
return int("".join(digits)) + int(f"11{'0' * (mid - 2)}")
left[-1] = f"{int(left_d) + 1}"
return "".join(left + left[::-1])
t = int(input())
for i in range(t):
n = int(input())
print(next_palindrome(n))