Also, it is usual (and very useful) to use an if __name__ == '__main__':
guard if __name__ == '__main__':
guard so that you have your definitions (classes, functions, constants, etc) on one hand and your actual program doing something on the other hand.
Also, it is usual (and very useful) to use an if __name__ == '__main__':
guard so that you have your definitions (classes, functions, constants, etc) on one hand and your actual program doing something on the other hand.
Also, it is usual (and very useful) to use an if __name__ == '__main__':
guard so that you have your definitions (classes, functions, constants, etc) on one hand and your actual program doing something on the other hand.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. If the numberBased on the left ("d1...dk") is bigger thancomparison of the reversed number onleft part and of the right ("dn..dk+1")part, the next palindrom is obtained by reversing the beginningleft part and putting it at the end "d1..dk.d(k+1).dk...d1". If not, the next palindrom is constructed the same way except thatits reversed with either
dk
ordk+1
in the middle component needs to be incremented : "d1..dk.((dk)+1).dk...d1". This is actually wrong, also I have chosen a pretty bad notation but you get the spirit.if n is even, the same logic applies without a middle component.
A few edge cases are to be considered but I'll let you play with thisthe following code works on basic cases :
def next_palindrome(a):
s = str(a)
n = len(s)
k, r = divmod(n, 2)
if r:
left, mid, right = s[:k], s[k], s[k+1:]
assert len(left) == len(right) == k
assert s == left + mid + right
print(s, left, mid, right)
mid_n = int(mid)
if left:
left_n, right_n, right_n_rev = int(left), int(right), int(right[::-1])
if left_n > right_n and left_n > right_n_rev:
return int(left + mid + left[::-1])
else:
return int(left + str(mid_n+1) + left[::-1])
else:
return mid_n # 1-digit number
else:
left, right = s[:k], s[k:]
assert len(left) == len(right) == k
assert s == left + right
print(s, left, right)
left_n, right_n, right_n_rev = int(left), int(right), int(right[::-1])
if left_n > right_n and left_n > right_n_rev:
return int(left + left[::-1])
else:
new_left = str(left_n + 1)
return int(new_left + new_left[::-1])
I've tried (unsucessfully) to give meaningful names to variables.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. If the number on the left ("d1...dk") is bigger than the reversed number on the right ("dn..dk+1"), the next palindrom is obtained by reversing the beginning and putting it at the end "d1..dk.d(k+1).dk...d1". If not, the next palindrom is constructed the same way except that the middle component needs to be incremented : "d1..dk.((dk)+1).dk...d1". This is actually wrong, also I have chosen a pretty bad notation but you get the spirit.
if n is even, the same logic applies without a middle component.
A few edge cases are to be considered but I'll let you play with this.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. Based on the comparison of the left part and of the right part, the next palindrom the left part and its reversed with either
dk
ordk+1
in the middle.if n is even, the same logic applies without a middle component.
A few edge cases are to be considered but the following code works on basic cases :
def next_palindrome(a):
s = str(a)
n = len(s)
k, r = divmod(n, 2)
if r:
left, mid, right = s[:k], s[k], s[k+1:]
assert len(left) == len(right) == k
assert s == left + mid + right
print(s, left, mid, right)
mid_n = int(mid)
if left:
left_n, right_n, right_n_rev = int(left), int(right), int(right[::-1])
if left_n > right_n and left_n > right_n_rev:
return int(left + mid + left[::-1])
else:
return int(left + str(mid_n+1) + left[::-1])
else:
return mid_n # 1-digit number
else:
left, right = s[:k], s[k:]
assert len(left) == len(right) == k
assert s == left + right
print(s, left, right)
left_n, right_n, right_n_rev = int(left), int(right), int(right[::-1])
if left_n > right_n and left_n > right_n_rev:
return int(left + left[::-1])
else:
new_left = str(left_n + 1)
return int(new_left + new_left[::-1])
I've tried (unsucessfully) to give meaningful names to variables.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. If the number on the left ("d1...dk") is bigger than the reversed number on the right ("dn..dk+1"), the next palindrom is obtained by reversing the beginning and putting it at the end "d1..dk.d(k+1).dk...d1". If not, the next palindrom is constructed the same way except that the middle component needs to be incremented : "d1..dk.((dk)+1).dk...d1". IThis is actually wrong, also I have chosen a pretty bad notation but you get the spirit.
if n is even, the same logic applies without a middle component.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. If the number on the left ("d1...dk") is bigger than the reversed number on the right ("dn..dk+1"), the next palindrom is obtained by reversing the beginning and putting it at the end "d1..dk.d(k+1).dk...d1". If not, the next palindrom is constructed the same way except that the middle component needs to be incremented : "d1..dk.((dk)+1).dk...d1". I have chosen a pretty bad notation.
if n is even, the same logic applies without a middle component.
if n is odd, we have $$n = 2*k+1$$ and we have 3 parts : $$d1,d2,..,dk$$ in the piece of the left, $$dk+1$$ in the middle, $$dk+2..dn$$ in the piece on the right. If the number on the left ("d1...dk") is bigger than the reversed number on the right ("dn..dk+1"), the next palindrom is obtained by reversing the beginning and putting it at the end "d1..dk.d(k+1).dk...d1". If not, the next palindrom is constructed the same way except that the middle component needs to be incremented : "d1..dk.((dk)+1).dk...d1". This is actually wrong, also I have chosen a pretty bad notation but you get the spirit.
if n is even, the same logic applies without a middle component.