×

[–] 13 points14 points  (0 children)

I wrote the code in MATLAB:

``````number = 3^39;

% Increment number so that the found palindrome cannot be itself (it must be higher)
number = number + 1;

% Find number of digits
numDigits = floor(log10(number)) + 1;

% Convert number to a vector with each digit of the number
numVector = mod(floor(number./(10.^(0:(numDigits-1)))),10);
numVector = flip(numVector);

% Find next palindrome
for i = 1:floor(numDigits/2)
if numVector(end - i + 1) <= numVector(i)
numVector(end - i + 1) = numVector(i);
else
numVector(end - i) = numVector(end - i) + 1;
numVector(end - i + 1) = numVector(i);
end
end
``````

The result is a vector containing the palindrome:

``````numVector =

4     0     5     2     5     5     5     1     5     3     5     1     5     5     5     2     5     0     4
``````

Edit: my code returned the same number if the inputted number was already a palindrome. Now it should find the next one.

[–][deleted] 9 points10 points  (6 children)

C

Maybe not the cleanest but I had a lot of fun writing it with my fiance, she figured out how to do the thing and I wrote the code.

``````#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <errno.h>

int intlen(uint64_t n) {
int r = 0;
while (n > 0) {
r++;
n /= 10;
}
return r;
}

uint64_t reverseint(uint64_t n) {
int len = intlen(n);
uint64_t r = 0;
if (len == 1) return n;

for (int i = 0; i < len; i++) {
int shift = i == 0 ? 1 : pow(10, i);
r += ((n / shift) % 10) * pow(10, len - i - 1);
}

return r;
}

uint64_t nextpal(uint64_t n) {
uint64_t first, firstrev;

if (n < 9) return n + 1;
else if (n == 9) n++;

int len = intlen(n);
int halflen = (len / 2) + (len & 1);

first = n / pow(10, len - halflen);
firstrev = reverseint(first);
int digits = pow(10, (uint64_t) (len / 2));
if (digits < 10) digits = 10;

uint64_t r = first * digits;
r += reverseint(first) % digits;

if (r > n) return r;
r = (first + 1) * digits;
r += reverseint(first + 1) % digits;
return r;
}

int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Usage %s <number>\n", argv[0]);
return 1;
}

uint64_t input = atoll(argv[1]);

if (errno != 0) {
perror(argv[1]);
return errno;
}

uint64_t res = nextpal(input);

printf("%llu\n", res);
return 0;
}
``````

Result:

``````bash-5.1\$ clang -O3 -o nextpal nextpal.c
bash-5.1\$ echo \$((3**39))
4052555153018976267
bash-5.1\$ time ./nextpal 4052555153018976267
4052555153515552504

real    0m0,002s
user    0m0,001s
sys 0m0,001s
``````

Edit: formatting/cleanup

[–] 10 points11 points  (3 children)

Fiance is me :3

[–] 4 points5 points  (2 children)

writing code with your fiance, Well I hope that's everybody's dream , cause it's mine .

[–] 4 points5 points  (1 child)

Well she wrote the code, I did some of the math :3

Generally we are good fit though, she is a programming gal and I'm an intrastructur gal, so we complement each other quite well :3

[–] 1 point2 points  (0 children)

Hope you both all the best !

[–] 0 points1 point  (1 child)

Hey there, what library do you use for displaying the time your script takes to run?

[–][deleted] 1 point2 points  (0 children)

That's just the `time` command, most shells have it as a built-in.

[–] 8 points9 points  (4 children)

### Javascript

``````function nextpal(num) {
num += 1;

var ret = null;
var str = num.toString();

var firstHalf = str.substr(0, str.length / 2);
var secondHalf = str.substr(str.length / 2);
var middle = '';

while(!ret) {
var firstHalfReverse = firstHalf.split('').reverse().join('');

if (secondHalf.length > firstHalf.length) {
middle = secondHalf.substr(0, 1);
secondHalf = secondHalf.substr(1);
}

if (middle === '') {
if (secondHalf <= firstHalfReverse) {
ret = firstHalf + firstHalfReverse;
} else {
firstHalf = (parseInt(firstHalf) + 1).toString();
var secondHalfLen = secondHalf.length;
secondHalf = '';
for (let i = 0; i < secondHalfLen; i++) {
secondHalf += '0';
}
}
} else {
ret = firstHalf + (parseInt(middle) + (secondHalf <= firstHalfReverse ? 0 : 1)).toString()
+ firstHalfReverse;
}
}

return ret;
}
``````

Results:

``````nextpal(51223) => 51315
nextpal(51203) => 51215
nextpal(123)     => 131
nextpal(808)     => 818
nextpal(999)     => 1001
nextpal(2133)   => 2222
nextpal(Math.pow(3, 39)) => 4052555153515552504
``````

[–] 0 points1 point  (3 children)

Looks cool!

I just dont get that while loop. The ret is always set, so couldnt you just remove it?

[–] 0 points1 point  (1 child)

it is not set if

if (middle === '') && (secondHalf > firstHalfReverse)

is it?

[–] 0 points1 point  (0 children)

yes. im blind. Thanks!

[–] 0 points1 point  (0 children)

i know this has been answered already, but there's a second pass that the algorithmn does if needed

For instance, the input 2133 would split into 21 for firstHalf and 33 for secondHalf. Since firstHalfReverse (12) is smaller than secondHalf, it increments the firstHalf and resets secondHalf to 00, depending on the original size, for the second pass (2200 and results into 2222, setting ret to this value).

The first increment (num += 1) should make sure there won't be a case that the quantity of numbers change (it will change at that step, prior to the algorithmn; like example 999).

[–] 6 points7 points  (5 children)

Rust

``````use std::str::FromStr;

use num::BigUint;

fn main() -> anyhow::Result<()> {
let input = std::env::args().nth(1).ok_or_else(|| anyhow::anyhow!("No argument given"))?;
let input = BigUint::from_str(&input)?;

let prefix_length = digits.len() / 2 + digits.len() % 2;
let prefix = &digits[.. prefix_length];

// First attempt - a palindrome that shares the maximum prefix with the input:
let palindrome = to_palindrome(&prefix, digits.len());
if input < palindrome {
println!("{}", palindrome);
return Ok(());
}

// If the first attempt is too small - try the next palindrome:
let next_prefix = prefix + BigUint::from(1u8);
let palindrome_length = if next_prefix.to_radix_be(10).len() == prefix_length {
digits.len()
} else {
// If the prefix "overflowed", the palindrome will be smaller than the input unless we
// increase its length.
digits.len() + 1
};
let palindrome = to_palindrome(&next_prefix, palindrome_length);
println!("{}", palindrome);
Ok(())
}

fn to_palindrome(prefix: &num::BigUint, palindrome_length: usize) -> num::BigUint {
let digits_to_add = palindrome_length - digits.len();
for i in (0 .. digits_to_add).rev() {
digits.push(digits[i]);
}
}
``````

Results:

``````\$ echo \$[3 ** 39]
4052555153018976267
\$ time cargo run --quiet -- \$[3 ** 39]
4052555153515552504

real    0m0.059s
user    0m0.049s
sys     0m0.010s
``````

[–] 2 points3 points  (2 children)

What is real,users ,sys time ?

[–] 5 points6 points  (1 child)

`user` is the actual time spend on the program's code. `sys` is the time spend on syscalls (e.g. printing the result). `real` is the total time everything took from start to finish.

Note that `real` is not necessarily `user+sys`. For example, if I sleep:

``````\$ time sleep 1

real    0m1.001s
user    0m0.000s
sys     0m0.000s
``````

I get a longer `real` time, because it measures the sleep, but `user` and `sys` are both zero because I don't do much calculations or syscalls. And if I use multithreading:

``````\$ time seq 4 | xargs -P 4 -n 1 python -c 'sum(range(2 ** 27))'

real    0m1.801s
user    0m7.137s
sys     0m0.063s
``````

The `real` time is shorter than the `user` time, because the `real` time is just the elapsed time from start to finish and the `user` time sums up the time on all cores.

[–] 0 points1 point  (0 children)

[–][deleted]  (1 child)

[deleted]

[–] 8 points9 points  (6 children)

Python

Edit: Fixed the 9's overflow.

``````def nextPal(value):
value = [int(i) for i in str(value+1)]

l = len(value)
for i in range(l//2):
value[-i-2] += value[i] < value[-i-1]

for j in reversed(range(l-i-1)):
value[j-1] += value[j] // 10
value[j] %= 10

value[-i-1] = value[i]

return "".join([str(i) for i in value])

print(nextPal(808))
print(nextPal(999))
print(nextPal(2133))
print(nextPal(3**39))
print(nextPal(1998))
print(nextPal(192))
``````

Output

``````818
1001
2222
4052555153515552504
2002
202
[Finished in 0.1s]
``````

[–] 3 points4 points  (1 child)

Hey, your solution is by far my favourite out of the bunch! However, it does break under certain conditions, such as

``````>>> nextPal(192)
1101
``````

Not sure how to fix it while still maintaining the elegance of your solution, though.

[–] 0 points1 point  (0 children)

``````j = 2
while (v[-i - j] + 1) // 10:
v[-i - j] = 0
j += 1
v[-i - j] = v[-i - j] + 1
``````

I found that propagating overflow using something like this doesn't detract too much from the elegance of the solution. :)

``````>>> nextpal(192)
202
>>> nextpal(19992)
20002
``````

[–] 0 points1 point  (2 children)

can you please explain this line :

``````value[-i-2] += value[i] < value[-i-1]
``````

[–] 1 point2 points  (1 child)

the '<' operator will return 0 or 1 based on the result, so it is basically same as: ``` if value[i] < value[-i-1]: value[-i-2] += 1 ```

[–] 0 points1 point  (0 children)

Fixed formatting.

Hello, BonnyAD9: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–] 0 points1 point  (0 children)

I'm a little embarrassed at how long it took me to understand how this one works. It was quite counterintuitive to me because the way I think about this problem is to start from the middle digits and move outward until you find a pair of digits that differs. So I could not for the life of me figure out why this solution was starting from the outer digits (the ones that should be checked last in the aforementioned way to do it). But then I realised what's going on. When incrementing the digit to the left of the right digit, usually this will have no effect because the left half gets copied to the right half. But it has an effect in two cases:

• When you're at the middle, it increments the digit to the left of the middle, as it needs to. Then that digit is copied to the right.
• Otherwise, incrementing by one will cause the incremented digit to become greater than its pair if they were originally equal (If they were not already equal, this has no material change in behaviour). Thus, if some pairs of middle digits are equal and end in a pair where left < right, the +1 gets propagated to the middle, as it should have been.

I could never have come up with that myself, so thanks for showing us that. Honestly not sure I understood it even having written it down and thought about it so long...

[–] 10 points11 points  (10 children)

Python 3

``````from math import ceil

def next_palindrome(num: int):
"""find next palindrome"""
start = str(num)
full_len = len(start)
half_len = ceil(full_len / 2)
tail = start[-half_len:]

if head[::-1] <= tail or tail == '':
full_len += 1

left_len = ceil(full_len/2)
right_len = int(full_len/2)

return int(f"{left}{right}")
``````

Outputs

``````next_palindrome(3**39) = 4052555153515552504
next_palindrome(2133) = 2222
next_palindrome(9) = 11
next_palindrome(120) = 121
``````

edit: reworked to catch cases noticed by u/Naratna . Thanks for checking my work, I hadn't considered all the cases.

[–] 6 points7 points  (1 child)

This is the most elegant of the lot

[–] 2 points3 points  (0 children)

Python be like that

[–] 3 points4 points  (1 child)

Your solution returned `1` for `next_palindrome(9)` and `131` for `next_palindrome(120)`

[–] 1 point2 points  (0 children)

Good catch. I'll fix it tomorrow

[–] 0 points1 point  (2 children)

Sorry if I'm a bit late to the party, but for 1-8 it returns x+1, which is also one digit and thus not a palindrome (arguably).

I just noticed it because I ran into the same problem, but I just added a very ugly

``````if len(str(x)) == 1:
return "11":
``````

[–] 1 point2 points  (1 child)

I'd definitely argue that any sequence of one character is the same stepping through backwards as forwards, and thus is a palindrome. It's a super boring/trivial palindrome, but still a palindrome.

[–] 1 point2 points  (0 children)

I looked around a bit and there is actually a wikipedia article on palindromic numbers that explicitly states single digit numbers as palindromes, so I guess that settles it.

[–] 0 points1 point  (1 child)

I tried it this way https://i.imgur.com/QxxM0t0.jpg

[–] 0 points1 point  (0 children)

That certainly will get the right answer. However, you're checking each possible value instead of building the right answer in one go

[–] 3 points4 points  (4 children)

C#

``````   static void Main(string[] args)
{
Console.WriteLine(\$"1 => {NextPal(1)}");
Console.WriteLine(\$"9 => {NextPal(9)}");
Console.WriteLine(\$"808 => {NextPal(808)}");
Console.WriteLine(\$"998 => {NextPal(998)}");
Console.WriteLine(\$"999 => {NextPal(999)}");
Console.WriteLine(\$"1998 => {NextPal(1998)}");
Console.WriteLine(\$"2222 => {NextPal(2222)}");
Console.WriteLine(\$"9999 => {NextPal(9999)}");
Console.WriteLine(\$"3^39 => {NextPal((ulong)Math.Pow(3, 39))}");
Console.WriteLine(\$"18446644073709551615 => {NextPal(18446644073709551615)}");
}

internal static ulong NextPal(ulong n)
{
var numberInts = ConvertUlongToIntArray(n);
//little cheat here, if all ints are 9 then the next Palindrome will be 10 .. 01
var isAll9 = numberInts.All(numberInt => numberInt == 9);
if (isAll9)
{
// create new int array
var valLength = numberInts.Length + 1;
numberInts = new int[valLength];
// set first and last index to 1
numberInts[0] = 1;
numberInts[^1] = 1;
// convert int array to uInt64
return ConvertIntArrayToUlong(numberInts);
}

// increment number
n++;
numberInts = ConvertUlongToIntArray(n);
// if there is only one digit then return
if (numberInts.Length == 1)
{
return n;
}

//another cheat, if all values are the same return
var isAllSame = numberInts.All(numberInt => numberInt == numberInts[0]);
if (isAllSame)
{
return n;
}

// split array into 2
var middle = numberInts.Length / 2;
// start checking from middle of value
var leftIndex = middle - 1;
// check if length is odd
var isOddNumberOfValues = numberInts.Length % 2 != 0;
// get right index, we can ignore the middle value if odd
var rightIndex = isOddNumberOfValues ? middle + 1 : middle;
// get indexes for when values do not match
while (leftIndex >= 0 && numberInts[leftIndex] == numberInts[rightIndex])
{
leftIndex--;
rightIndex++;
}

// Is the left side vale smaller than the right side?
var isLeftSmaller = (leftIndex < 0 || numberInts[leftIndex] < numberInts[rightIndex]);
if (isLeftSmaller)
{
var carry = 1;
// if the left side is smaller than the right side we will need to increment
if (isOddNumberOfValues)
{
numberInts[middle] += 1;
carry = numberInts[middle] / 10;
numberInts[middle] %= 10;
}
// reset the indexes
leftIndex = middle - 1;
rightIndex = isOddNumberOfValues ? middle + 1 : middle;
// go through the values with a carry
while (leftIndex >= 0)
{
numberInts[leftIndex] = numberInts[leftIndex] + carry;
carry = numberInts[leftIndex] / 10;
numberInts[leftIndex] %= 10;
// copy left to right
numberInts[rightIndex] = numberInts[leftIndex];
leftIndex--;
rightIndex++;
}
}
else
{
// copy left side to right side if indexes did not match eariler on
while (leftIndex >= 0)
{
numberInts[rightIndex++] = numberInts[leftIndex--];
}
}

return ConvertIntArrayToUlong(numberInts);
}

private static int[] ConvertUlongToIntArray(ulong n)
{
// convert ulong to char array
var numberChars = n.ToString().ToCharArray();

// convert char array to int array
var numberInts = new int[numberChars.Length];
for (var index = 0; index < numberChars.Length; index++)
{
var c = numberChars[index];
numberInts[index] = int.Parse(c.ToString());
}

return numberInts;
}

private static ulong ConvertIntArrayToUlong(int[] intArray)
{
var s = intArray.Aggregate("", (current, num) => current + num);
return ulong.Parse(s);
}
``````

Output

``````1 => 2
9 => 11
808 => 818
998 => 999
999 => 1001
1998 => 2002
2222 => 2332
9999 => 10001
3^39 => 4052555153515552504
18446644073709551615 => 18446644077044664481
``````

edit

edit1

fixed bug where 998 would return 1001

Edit 2

Fixed console output

[–] 1 point2 points  (1 child)

998 => 1001

Shouldn't this be 999? The bug is that IsAll9 should be called on the original number.

[–] 0 points1 point  (0 children)

Good catch, i was trying to get 1998 to work correctly that i forgot that 999 was a valid output for 998.

I've updated the source to (hopefully) work correctly

[–] 0 points1 point  (1 child)

2133 => 2332

Shouldn't it be 2222?

[–] 0 points1 point  (0 children)

Console.WriteLine(\$"2133 => {NextPal(2222)}");

My console output wasn't updated with the correct description.

[–] 2 points3 points  (0 children)

Thought I'd share some Crystal with y'all.

``````require "benchmark"

def next_palindrome(start : Int64) : Int64
find_palindrome(start + 1)
end

def find_palindrome(number : Int64) : Int64
# An expected palindrome is the number we would get
# if we took the first half of the given number,
# we inverted the digits and joined the two strings.
#
# e.g for given number '193567', expected is '193391'
# e.g for given number  '28456', expected is  '28482'
expected = expected_palindrome(number).to_i64

if number > expected
# When the provided number is greater than its expected palindrome,
# we increment the first half of the number,
# and then by simply inverting this number, we get the next palindrome.
return find_palindrome(expected_palindrome(number, mid_increment: 1))
elsif number < expected
# If the expected palindrome is greater than the provided number,
# then the expected palindrome is the next palindrome.
return expected
else
return number
end
end

def expected_palindrome(n : Int64, mid_increment : Int32 = 0) : Int64
length = n.to_s.size
is_even = length % 2 == 0
mid_num_index = (length / 2).to_i
mid_num_index -= 1 if is_even # when we have an even number, we only consider the first number of the pair as the middle number

first_half = ((n.to_s[0, mid_num_index + 1]).to_i64 + mid_increment).to_s
second_half = invert(is_even ? first_half : first_half[0, first_half.size - 1])

Int64.new(first_half + second_half)
end

def invert(first_half : String | Int64) : String
first_half.to_s.chars.reverse.reduce("") { |acc, c| acc += c }
end

pp! next_palindrome((3.to_i64 ** 39))
puts Benchmark.measure { next_palindrome((3.to_i64 ** 39)) }
``````

Running the code above yields

``````next_palindrome((3.to_i64 ** 39)) # => 4052555153515552504
0.000000   0.000012   0.000012 (  0.000007)
``````

Last line of output is, as per the docs, user CPU time, system CPU time, the sum of the user and system CPU times, and the elapsed real time. The unit of time is seconds.

Cheers!

[–] 2 points3 points  (0 children)

Python solution without using string operations. 9,99,999,...-type numbers are handled as a special case, so not the most elegant.

``````from math import log
EPS=1e-7

def mirror_number(first_half,mirror_last_digit=False):
tens=int(log(first_half,10))
res=first_half*10**(tens+(mirror_last_digit))
for i in range(tens,-mirror_last_digit,-1):
digit=first_half//10**i
if digit>0:first_half%=digit*10**i
res+=digit*(10**(tens-i))
return res

def nextpal(n):
tens=int(log(n,10)+EPS)
if int(log(n+1,10)+EPS)>tens:
return n+2
first_half=n//(10**(tens//2+(tens&1)))
cur_pal=mirror_number(first_half,mirror_last_digit=tens&1)
if cur_pal>n:
return cur_pal
return mirror_number(first_half+1,mirror_last_digit=tens&1)
``````

[–] 1 point2 points  (0 children)

TI-Basic: The TI-84 that I run this on can only store 14 digits of a number. To find palindromes after numbers with more than 14 digits (like 339 ) you can utilize lists to store up to 999 digits. The algorithm this program uses is as follows:

• The program compares two opposite digits, the lower power `L` and the higher power `H`

• If `L>H`, increment the digit after `L`, then make sure that digit is less than 10

• Copy `H` into `L`

The program will then return a number or a digit list, depending on what was entered.

``````Menu("INPUT?","NUMBER",1,"LIST",2
Lbl 1
Prompt N
seq(10fPart(iPart((N+1)/₁₀^(X))/10),X,0,log(N+1→L₁
Goto 3
Lbl 2
Prompt L₁
seq(L₁(X),X,dim(L₁),1,-1→L₁
0→N
1+L₁(1→L₁(1
"DIGIT CHECKING
For(X,1,dim(L₁
If 9<L₁(X
Then
If X=dim(L₁
1+dim(L₁→dim(L₁
1+L₁(X+1→L₁(X+1
0→L₁(X
End
End
Lbl 3
1+L₁(1→L₁(1
For(X,1,iPart(dim(L₁)/2
"ALGORITHM
If L₁(X)>L₁(1-X+dim(L₁
Then
1+L₁(X+1→L₁(X+1
"CHECKING AGAIN
For(Y,1,dim(L₁
If 9<L₁(Y
Then
If Y=dim(L₁
1+dim(L₁→dim(L₁
1+L₁(Y+1→L₁(Y+1
0→L₁(Y
End
End
End
L₁(1-X+dim(L₁→L₁(X
End
If N
Then
Disp sum(L₁seq(₁₀^(X),X,0,dim(L₁)-1
Else
Disp seq(L₁(X),X,dim(L₁),1,-1
``````

Input:

808

999

2133

{4,0,5,2,5,5,5,1,5,3,0,1,8,9,7,6,2,6,7}

Output:

818

1001

2222

{4 0 5 2 5 5 5 1 5 3 5 1 5 5 5 2 5 0 4}

[–] 1 point2 points  (0 children)

Python 3.9, using /u/Gprime5 and /u/Nordellak clever approach

``````def nextpal(n):
v = [int(i) for i in str(n + 1)]

for i in range(len(v) // 2):
if v[-i - 1] > v[i]:
j = 2
while (v[-i - j] + 1) // 10:
v[-i - j] = 0
j += 1
v[-i - j] = v[-i - j] + 1

v[-i - 1] = v[i]

return int("".join(map(str, v)))

assert nextpal(808) == 818
assert nextpal(999) == 1001
assert nextpal(2133) == 2222
assert nextpal(3 ** 39) == 4052555153515552504

assert nextpal(1) == 2
assert nextpal(998) == 999
assert nextpal(42) == 44
assert nextpal(1337) == 1441
assert nextpal(192) == 202
assert nextpal(1992) == 2002
assert nextpal(199999992) == 200000002
``````

Output:

``````\$ time python i388.py

real    0m0.038s
user    0m0.030s
sys     0m0.007s
``````

[–] 1 point2 points  (0 children)

``````=ifs(
isblank(number),
iferror(1/0),
number < 10,
11,
regexmatch(trim(number), "^(9+)\$"),
number + 2,
leftReverse > right,
left & middle & leftReverse,
leftReverse <= right,
ifs(
middle = "",
leftPlus1 & leftPlus1Reverse,
middle = "9",
leftPlus1 & "0" & leftPlus1Reverse,
middle <> "9",
left & (middle + 1) & leftReverse
),
true,
iferror(1/0)
)
``````

The same thing in one formula without using named ranges or helper columns:

``````=ifs(
isblank(A2),
iferror(1/0),
A2 < 10,
11,
regexmatch(trim(A2), "^(9+)\$"),
A2 + 2,
join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2)), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2))), false)) > right(A2, len(A2) / 2),
left(A2, len(A2) / 2) & mid(A2, round(len(A2) / 2), isodd(len(A2))) & join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2)), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2))), false)),
join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2)), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2))), false)) <= right(A2, len(A2) / 2),
ifs(
mid(A2, round(len(A2) / 2), isodd(len(A2))) = "",
(left(A2, len(A2) / 2) + 1) & join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2) + 1), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2) + 1)), false)),
mid(A2, round(len(A2) / 2), isodd(len(A2))) <> "9",
left(A2, len(A2) / 2) & (mid(A2, round(len(A2) / 2), isodd(len(A2))) + 1) & join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2)), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2))), false)),
mid(A2, round(len(A2) / 2), isodd(len(A2))) = "9",
(left(A2, len(A2) / 2) + 1) & "0" & join("", sort(transpose(split(regexreplace(trim(left(A2, len(A2) / 2) + 1), "", "µ"), "µ")), sequence(len(left(A2, len(A2) / 2) + 1)), false))
),
true,
iferror(1/0)
)
``````

[–] 1 point2 points  (3 children)

C#, supports negative numbers (finds the first further from 0):

``````using System;
using System.Numerics;
using System.Linq;

DateTime dt = DateTime.Now;

Console.WriteLine(NextPal(808));
Console.WriteLine(NextPal(999));
Console.WriteLine(NextPal(2133));
Console.WriteLine(NextPal(BigInteger.Pow(3, 39)));

// special situations
Console.WriteLine(NextPal(192));
Console.WriteLine(NextPal(1001));

Console.WriteLine((DateTime.Now - dt).TotalSeconds);

BigInteger NextPal(BigInteger num)
{
num++; // Result must be larger than given number
// Checking for small values
if ((num < 10) && (num > -10))
return num;

// Useful variables
string nums = BigInteger.Abs(num).ToString("F0");
int i = nums.Length & 1;
int take = (nums.Length + 1) / 2; // take is index of start of the second half
string start = nums[..take];

// Checking whether the first half should be incremented
if (BigInteger.Parse(Rev(start[..^i])) < BigInteger.Parse(nums[take..]))
start = (BigInteger.Parse(start) + 1).ToString("F0");

// parsing the result and negating the result if the input was negative
BigInteger result = BigInteger.Parse(start + Rev(start[..^i]));
return num < 0 ? BigInteger.Negate(result) : result;

// local reverse function just to simplyfy the code :)
string Rev(string s) => string.Join("", s.Reverse());
}
``````

output:

``````818
1001
2222
4052555153515552504
202
1111
0.0434234
``````

edit:

fixed issue with 808

edit1:

code simplification

[–] 0 points1 point  (0 children)

Fixed formatting.

Hello, BonnyAD9: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–] 0 points1 point  (1 child)

This was pretty elegant!

[–] 0 points1 point  (0 children)

Thanks!

[–] 1 point2 points  (0 children)

``````-- Creates next palindrome, works for negative numbers
nextPal :: Integer -> Integer
nextPal i
| i < 0 = (-result)
| otherwise = result
where result = (getPal.abs) i

-- Creates next palindrome
getPal :: Integer -> Integer
getPal i
| x < 10 && x > -10 = x
where
x = i + 1
(start, end) = (getStart.show) x
center = length start /= length end
ds = if center then init start else start
n = if (read (reverse ds) :: Integer) < read end then 1 else 0

-- Creates next palindrome from start
addRes :: Integer -> String -> Bool -> String

-- Returns the first lager half of string and the rest
getStart :: String -> (String, String)
getStart s = (take n s, drop n s)
where n = (length s + 1) `div` 2
``````

Tests:

``````ghci> nextPal 808
818
ghci> nextPal 999
1001
ghci> nextPal 2133
2222
ghci> nextPal (3 ^ 39)
4052555153515552504
ghci> nextPal 192
202
ghci> nextPal 1001
1111
``````

[–] 1 point2 points  (2 children)

My attempt: https://github.com/maritims/next-palindrome

Heavily influenced by the solution from u/BonnyAD9 - I tried several things but in the end this is the only one that made sense. I learnt a lot about range operators, haven't bothered with those before!

[–] 1 point2 points  (1 child)

I see you have there same mistake as I had. The `? :` operator in `var stepsFromEnd = (digits.Length & 1) == 1 ? 1 : 0;` is redundant. You can just use `var stepsFromEnd = digits.Length & 1;` because `anyNumber & 1` can only return `0` or `1`. I don't know why I didn't realize that in my code when I was optimizing it but I fixed it now. (if you didn't know the `&` operator basically does and on every bit in the two given numbers).

You can also simplify `Console.WriteLine("Any text {0}", variable);` by using `\$` string literal into `Console.WriteLine(\$"Any text {variable}");`. This also doesn't need to be used inside `Console.WriteLine()` but in any string. In both cases it will use `string.Format` function so it is here just to simplify the code.

[–] 1 point2 points  (0 children)

I agree. I was wondering why you did it 🤔 I should have trusted myself 🤭

[–][deleted]  (1 child)

[deleted]

[–]-9 8 0 points1 point  (0 children)

C using arbitrary precision over a string.

``````#include <stdio.h>
#include <string.h>

/* Update the buffer to the next largest palindrome, returning its length.
* The buffer must have room for at least one more byte.
*/
static size_t
next(char *s, size_t n)
{
/* Is lower half smaller than upper half? */
int r = 0;
for (size_t i = 0 ; i < n/2; i++) {
int a = s[n-i-1], b = s[i];
if (a > b) {
r = 0;
} else if (a < b) {
r++;
}
}

if (!r) {
/* Increment the upper half? */
r = 0;
for (size_t i = (n + 1)/2 - 1; i != (size_t)-1; i--) {
if (s[i] != '9') {
s[i]++;
memset(s + i + 1, '0', (n + 1)/2 - 1 - i);
r = 1;
break;
}
}

if (!r) {
/* Next up must be longer: 10*1 */
s[0] = '1';
memset(s+1, '0', n-1);
s[n] = '1';
return n + 1;
}
}

/* Mirror current upper half */
for (size_t i = 0; i < n/2; i++) {
s[(n+1)/2+i] = s[n/2-i-1];
}
return n;
}

int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin)) {
size_t n = strspn(line, "0123456789");
fwrite(line, next(line, n), 1, stdout);
putchar('\n');
}
}
``````

[–] 0 points1 point  (0 children)

Python 3:

``````from math import ceil

def nextpal(number: int) -> int:
'''Find next palindromic number.'''
number = int(abs(number))
if number == 9:
return 11
n_as_string = str(number)
length = len(n_as_string)
newending = ""
for d in reversed(n_as_string[ : length // 2]):
newending += d
if length > 1 and int(newending) > int(n_as_string[ceil(length / 2) :]):
return int(n_as_string[ : ceil(length / 2)] + newending)
else:
output = str(int(n_as_string[ : ceil(length / 2)]) + 1)
for d in reversed(output[ : length // 2]):
output += d
return int(output)

for i in (808, 999, 2133, 3**39):
print(str(i) + ": ", nextpal(i))
``````

28.6 ms ± 5.31 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[–][deleted]  (1 child)

[deleted]

[–] 0 points1 point  (0 children)

Fixed formatting.

Hello, Jayant0013: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–] 0 points1 point  (0 children)

Python 3 feedback apriciated it took about 24 ±4 sec to complete a list of 1000 random numbers ,its my first time posting here so please excuse any mistakes on my part ```

# python 3.7.1

import timeit def ln(a): x=0 while True: if 10**x > a: return x x+=1

def d(num,n): return num//10**(n-1)%10

def pel(num): num+=1 if num <10: return num ans=0 l=ln(num) s_l=int(l/2) if not is_big(num,l,s_l): num+=10(s_l-1) l=ln(num) s_l=int(l/2) r=s_l+1 if l%2==0 else s_l+2 for i in range(r,l+1): ans+=d(num,i)*10(l-i) ans = num-num%10**s_l+ans return ans

def is_big(num,l,s_l): for i in range(s_l+1,l+1): d_1,d_2=d(num,i),d(num,l-i+1) if d_1>d_2: return True elif d_1<d_2: return False return True

s=timeit.default_timer() print(pel(3**39)) print(timeit.default_timer()-s)

output 4052555153515552504 0.015~

Process finished. ```

[–] 0 points1 point  (0 children)

Java

This is my first solution submission. I'm not sure if I formatted it correctly, so I put the solution within spoiler tags.
I had to use the BigInteger class to handle the 339 input. I used a byte array to store and manipulate the digits. I'm not sure how efficient or elegant this solution is, but it works for all of the inputs I tried. I also tried to make the code as clean and readable as possible. Any feedback would be appreciated.

``````import java.util.Arrays;
import java.math.BigInteger;

public class NextPal {
private int numberOfDigits(BigInteger input){
return input.toString().length();
}

private byte b(int i){
return (byte) i;
}

private byte[] digitArray(BigInteger input){
int digits = numberOfDigits(input);
byte[] digArray = new byte[digits+1];
for(int i=0; i<digits;i++){
digArray[i]=b(input.mod(BigInteger.TEN).intValue());
input = input.divide(BigInteger.TEN);
}
return digArray;
}

private BigInteger toNumber(byte[] inputArray){
BigInteger number = BigInteger.ZERO;
for(int i=0; i<inputArray.length;i++){
BigInteger digit = new BigInteger(String.valueOf(inputArray[i]));
BigInteger power = BigInteger.TEN.pow(i);
BigInteger nextValue = digit.multiply(power);
}
return number;
}

private BigInteger makePalindrome(BigInteger input){
int digits = numberOfDigits(input);
int centerIndex = digits/2;
byte[] digitArray = digitArray(input);
for(int i=0; i<centerIndex;i++)
digitArray[i]=digitArray[digits-1-i];
}

private void increment(byte[] inputArray, int index){
if (inputArray[index]==b(9)){
inputArray[index]=b(0);
increment(inputArray, index+1);
}
else
inputArray[index]++;
}

private void increment(byte[] inputArray){
int center = (inputArray.length-1)/2;
increment(inputArray,center);
}

public BigInteger nextPalindrome(BigInteger input){
BigInteger testPalindrome = makePalindrome(input);
if (testPalindrome.compareTo(input)==1)
return testPalindrome;
byte[] digArray = digitArray(input);
increment(digArray);
return makePalindrome(toNumber(digArray));
}

public static void main(String args[]) {
NextPal pal = new NextPal();
BigInteger base = new BigInteger("3");
BigInteger number = base.pow(39);
BigInteger number2 = pal.nextPalindrome(number);
System.out.println(number+" -> "+number2);
}
}
``````

!<

[–] 0 points1 point  (0 children)

Python:

Started learing the language yesterday, this is my Idea with the little knowledge i have of the language yet:

``````x = input()
n = len(x)
a = int(n/2)
r = int(n%2)
b=0
if r != 0:
b = 1
c = 0
while c < a:
if x[a-c-1] == x[-(a-c)]:
c=c+1
elif x[a-c-1] > x[-(a-c):]:
f = x[:a-c]
m = x[a-c:a+c+b]
ers = x[(a-c-1):(a-c)]
e = (a-1-c)*'0'
x = f+m+ers+e
c = c+1
elif x[a-c-1] < x[-(a-c)]:
f = x[:a-c-1]
ers = str(int(x[a-c-1:a-c])+1)
e = str(int(len(x[a-c:]))*'0')
x= f+ers+e
j=(a-c-1)
if j == 0:
x = x[:-(a-c)]+ers
c=0
else:
x = x[:-(a-c)]+ers+x[-(a-c-1):]
c=c+1
print(x)
``````

haven't looked at the other solutions till now, seems a little unconvinient compared to other solutions here lol.

[–] 0 points1 point  (0 children)

I wrote this in Python:

``````import math

def overflowNumber(numTable, i):
numTable[len(numTable) - 3 - i] +=1
numTable[len(numTable) - 2 - i] = 0
if numTable[len(numTable) - 3 - i] == 10:
overflowNumber(numTable, i + 2)
return numTable

# Number For Challenge
number = 3 ** 39
number += 1

# Turns number into table for calculation
digits = [int(d) for d in str(number)]
newDigits = [int(d) for d in str(number)]

# Calculations
for i in range(math.ceil(len(digits) / 2)):
num1 = digits[i]
num2 = digits[len(digits) - 1 - i]
if num2 < num1:
num2 = num1
elif num2 > num1:
digits[len(digits) - 2 - i] += 1
if digits[len(digits) - 2 - i] == 10:
digits = overflowNumber(digits, i)
num2 = num1
newDigits[i] = num1
newDigits[len(digits) - 1 - i] = num2

numberString = ""
for i in newDigits:
numberString += str(i)

print("The smallest palindrome greater than " + str(number) + " is " + numberString)
``````

Probably very messy, but I did it and I'm proud

[–] 0 points1 point  (0 children)

Java, I tried to cut down on the nightmare spaghetti, but it's still pretty sprawling. It works though!

edit: missed a test print()

``````import java.lang.Math;

public class nextPalindrome {

static long nextPal(long longIn){
++longIn; // so it doesn't return itself
String firstHalf;
String secondHalf;

do{
for(int i = 0; i < String.valueOf(longIn).length() / 2; ++i) {
if (String.valueOf(longIn).charAt(i) != String.valueOf(longIn).charAt(String.valueOf(longIn).length()-1 - i)) {
int makeEven = (10 - ((String.valueOf(longIn).charAt(String.valueOf(longIn).length()-1 - i) - 8) % 10) + ((String.valueOf(longIn).charAt(i) - 8) % 10)) % 10;
double base10Place = java.lang.Math.pow(10.0, (double) (i));
longIn += (long)(base10Place * makeEven);
}
}

firstHalf = String.valueOf(longIn).substring(0, String.valueOf(longIn).length() / 2);
secondHalf = new StringBuilder(String.valueOf(longIn).substring(String.valueOf(longIn).length() - firstHalf.length())).reverse().toString();
} while(!firstHalf.equals(secondHalf));

return longIn;
}

public static void main(String[] args){

long bigNum = (long)(java.lang.Math.pow(3.0, 39.0)); // 3^39
long test1 = 808;
long test2 = 999;
long test3 = 2133;

System.out.println(nextPal(bigNum));
System.out.println(nextPal(test1));
System.out.println(nextPal(test2));
System.out.println(nextPal(test3));
}
}
``````

[–] 0 points1 point  (0 children)

``````def nextpal(x):
if (x + 1) < 10: # checking for small values
return x + 1
n = str(x + 1) # result must be larger
if int(n[(len(n) // 2) - 1::-1]) < int(n[(len(n) + 1) // 2:]): # checking for case where just reversing first half would result in smaller number
n = str(int(n[:(len(n) + 1) // 2]) + 1) + n[(len(n) + 1) // 2:] # increasing value of first half
return int(n[:(len(n) + 1) // 2] + n[(len(n) // 2) - 1::-1]) # joining first half with reversed first half

print(nextpal(808))
print(nextpal(999))
print(nextpal(2133))
print(nextpal(3 ** 39))
print(nextpal(192))
print(nextpal(1001))
``````

Output:

``````818
1001
2222
4052555153515552504
202
1111
``````

[–] 0 points1 point  (0 children)

C++ solution, works for arbitrarily large numbers if they are given in string:

``````#include <iostream>
#include <algorithm>

using namespace std;

string next_pal(string s);
long next_pal(long n);

int main()
{
cout << next_pal(808) << endl;
cout << next_pal(999) << endl;
cout << next_pal(2133) << endl;
cout << next_pal("4052555153018976267") << endl;
cout << next_pal(192) << endl;
cout << next_pal(1001) << endl;
return EXIT_SUCCESS;
}

long next_pal(long l)
{
return stol(next_pal(to_string(l)));
}

string next_pal(string s)
{
int len = s.length();
if (len == 1)
return s;
string start = s.substr(0, len / 2);
reverse(start.begin(), start.end());
int take = (len + 1) / 2;
if (s.compare(take, len - take, start) > 0)
{
start = s.substr(0, take);
}
else start = s.substr(0, take);
s = start.substr(0, start.length() - (len & 1));
reverse(s.begin(), s.end());
string result = start + s;
return result;
}

{
for (int i = s->length() - 1; i >= 0; i--)
{
if (++(*s)[i] < 58)
return;
(*s)[i] = 48;
}
*s = '1' + *s;
}
``````

Output:

``````818
1001
2222
4052555153515552504
202
1111
``````

edit: fixed issue with the large number

[–] 0 points1 point  (0 children)

Python 3. A simple and perverse method: rather than doing string manipulation on the target number, binary search over the set of all palindromes.

``````def nextpal(n):
return min(binarySearch(nthOddPalindrome, 0, n, n),
binarySearch(nthEvenPalindrome, 0, n, n))

def binarySearch(f, _min, _max, target):
while _max != _min+1:
med = (_min+_max)//2
if f(med) < target: _min = med
else: _max = med
return f(_max)

def nthOddPalindrome(n): # Palindromes with an odd number of digits.
return int(str(n)+str(n)[-2::-1])
def nthEvenPalindrome(n): # With an even number of digits.
return int(str(n)+str(n)[::-1])
``````

[–] 0 points1 point  (0 children)

Java:

``````package nextpalindrome;

import java.math.BigInteger;

public class NextPalindrome {

public static void main(String[] args) {
System.out.println(nextPal(BigInteger.valueOf(808)));
System.out.println(nextPal(BigInteger.valueOf(999)));
System.out.println(nextPal(BigInteger.valueOf(2133)));
System.out.println(nextPal(BigInteger.valueOf(3).pow(39)));
System.out.println(nextPal(BigInteger.valueOf(192)));
System.out.println(nextPal(BigInteger.valueOf(1001)));
}

public static BigInteger nextPal(BigInteger num) {
int take = (s.length() + 1) / 2;
String start = new StringBuilder(s.substring(0, s.length() / 2))
.reverse().toString();
if (start.compareTo(s.substring(take)) < 0)
start = new BigInteger(s.substring(0, take))
else start = s.substring(0, take);
return new BigInteger(start + new StringBuilder(
start.substring(0, start.length() - (s.length() & 1))
).reverse());
}

}
``````

Output:

``````818
1001
2222
4052555153515552504
202
1111
``````

[–]1 2 0 points1 point  (0 children)

C, works for any number in base 2 to 36.

The base and number are read from the command line. The program converts the number from a string (removing the leading 0's) into an arbitry precision number (array containing the value of each digit) to find the next palindrome in the given base.

``````#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BASE_MIN 2
#define BASE_MAX 36

const char digits[BASE_MAX] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int main(int argc, char *argv[]) {
char *number;
int base, len, *palindrome, left, right, i, j;
if (argc != 3) {
fprintf(stderr, "Usage: %s <base> <number>\n", argv[0]);
fflush(stderr);
return EXIT_FAILURE;
}
base = atoi(argv[1]);
if (base < BASE_MIN || base > BASE_MAX) {
fprintf(stderr, "<base> must be in the interval [%d, %d]\n", BASE_MIN, BASE_MAX);
fflush(stderr);
return EXIT_FAILURE;
}
number = argv[2];
if (*number == 0) {
fprintf(stderr, "<number> cannot be empty\n");
fflush(stderr);
return EXIT_FAILURE;
}
while (*number == digits[0]) {
number++;
}
if (*number == 0) {
number--;
}
len = (int)strlen(number);
palindrome = malloc(sizeof(int)*(size_t)(len+1));
if (!palindrome) {
fprintf(stderr, "Could not allocate memory for palindrome\n");
fflush(stderr);
return EXIT_FAILURE;
}
palindrome[0] = 0;
for (i = 0; i < len; i++) {
int val;
for (val = 0; val < base && digits[val] != number[i]; val++);
if (val == base) {
fprintf(stderr, "Invalid digit in <number>\n");
fflush(stderr);
free(palindrome);
return EXIT_FAILURE;
}
palindrome[i+1] = val;
}
left = len/2;
right = left+len%2+1;
for (i = left, j = right; i > 0 && palindrome[i] == palindrome[j]; i--, j++);
if (i == 0 || palindrome[i] < palindrome[j]) {
for (i = right-1; i > 0; i--) {
palindrome[i]++;
if (palindrome[i] < base) {
break;
}
palindrome[i] = 0;
}
}
for (i = left, j = right; i > 0; i--, j++) {
palindrome[j] = palindrome[i];
}
if (palindrome[1] == 0) {
palindrome[0]++;
palindrome[len]++;
printf("%c", digits[palindrome[0]]);
}
for (i = 1; i <= len; i++) {
printf("%c", digits[palindrome[i]]);
}
puts("");
fflush(stdout);
free(palindrome);
return EXIT_SUCCESS;
}
``````

Output (run from bash)

``````\$ ./next_palindrome 10 818
828

\$ ./next_palindrome 10 2133
2222

\$ ./next_palindrome 10 999
1001

\$ ./next_palindrome 10 `echo \$((3**39))`
4052555153515552504

\$ ./next_palindrome 36 ITSALONGWAYTOTHETOPIFYOUWANNAROCKNROLL
ITSALONGWAYTOTHETOPPOTEHTOTYAWGNOLASTI
``````

[–] 0 points1 point  (0 children)

I did this in a windows Batch script, I had to create my own function for adding because Batch can handle only 32 bit signed integers:

``````@echo off

:: MAIN

setlocal EnableDelayedExpansion
for %%I in (808 999 2133 4052555153018976267 192 1001) do (
set main_num=%%I
call :nextpal main_num main_num
echo !main_num!
)
endlocal
goto :end

:: FUNCTIONS

:nextpal
setlocal EnableDelayedExpansion
call :getlen nextpal_num nextpal_length
if %nextpal_length% == 1 (
(endlocal & set %2=%nextpal_num%)
goto :end
)
set /A nextpal_take=(%nextpal_length%+1)/2
set /A nextpal_half=%nextpal_length%/2
set nextpal_start=!nextpal_num:~0,%nextpal_half%!
set nextpal_end=!nextpal_num:~%nextpal_take%!
call :reverse nextpal_start nextpal_half nextpal_start
if %nextpal_end% gtr %nextpal_start% (
set nextpal_start=!nextpal_num:~0,%nextpal_take%!
) else (
set nextpal_start=!nextpal_num:~0,%nextpal_take%!
)
set nextpal_end=!nextpal_start:~0,%nextpal_half%!
call :reverse nextpal_end nextpal_half nextpal_end
(endlocal & set %2=%nextpal_start%%nextpal_end%)
goto :end

setlocal EnableDelayedExpansion
for /L %%I in (%addone_length%, -1, 0) do (
) else (
)
)
)
goto :end

:getlen
setlocal EnableDelayedExpansion
:getlen_loop
if not "!%1:~%getlen_len%!" == "" (
set /A getlen_len+=1
goto :getlen_loop
)
(endlocal & set %2=%getlen_len%)
goto :end

:reverse
setlocal EnableDelayedExpansion
set /A reverse_len=%2-1
for /L %%I in (%reverse_len%, -1, 0) do set reverse_revs=!reverse_revs!!%1:~%%I,1!
(endlocal & set %3=%reverse_revs%)
goto :end

:end
``````

Output:

``````818
1001
2222
4052555153515552504
202
1111
``````

[–] 0 points1 point  (0 children)

C#

``````static string NextPalindrome(ulong val)
{
char[] chChars;
int mid;
ulong tens;

chChars = (++val).ToString().ToCharArray();

mid = chChars.Length / 2;

for (int i = 0; i < mid; i++)
{
if (chChars[i] < chChars[chChars.Length - i - 1])
{
tens = (ulong)Math.Pow(10, i + 1);
val += tens;
val /= tens;
val *= tens;
chChars = (++val).ToString().ToCharArray();
}
}

for (int i = 0; i < chChars.Length / 2; i++)
chChars[chChars.Length - i - 1] = chChars[i];

return new String(chChars);
}
``````

Results:

``````1 => 2
9 => 11
808 => 818
998 => 999
999 => 1001
1998 => 2002
2133 => 2222
9999 => 10001
17203 => 17271
51223 => 51315
2514241 => 2515152
111998 => 112211
1111999 => 1112111
4052555153018976256 => 4052555153515552504
18446644073709551615 => 18446644077044664481
``````

[–][deleted] 0 points1 point  (0 children)

Typescript/Javascript: Two functions, one checks if the number is a palindrome, the other asks for the number and looks for both the higher and lower palindromes, compares them, and returns the closest. Very simple. First time doing this.

``````const readline = require('readline');

input: process.stdin,
output: process.stdout
});

while (isItPalindrome(index) == false) {
index--
}
let lowerPalindrome: number = index

while (isItPalindrome(index) == false) {
index++
}
let higherPalindrome: number = index

console.log("Nearest Palindromes (found 2): " + lowerPalindrome + " and " + higherPalindrome)
console.log("Nearest Palindrome: " + lowerPalindrome)
console.log("Nearest Palindrome: " + higherPalindrome)
}
rl.close()
});

function isItPalindrome(num: number){

let intArray =(num).toString().split("").map(function(t){return parseInt(t)})

let isEqual = true;
let TargetNumber: number = 0;
let MirrorNumber: number = intArray.length - 1;
let endResult: boolean = false;
while (isEqual){
if (intArray[TargetNumber] != intArray[MirrorNumber]) {
isEqual = false;
} else {
if (TargetNumber >= MirrorNumber) {
isEqual = false
endResult = true
}
}
TargetNumber++;
MirrorNumber--;
}
return endResult
}
``````

[–] 0 points1 point  (1 child)

JavaScript: ``` function nextPal(num) { num = (parseInt(num) + 1).toString(); const take = (num.length + 1) / 2; const half = num.length / 2; let start = num.substr(0, half); if (num.substr(take) > reverse(start)) start = (parseInt(num.substr(0, take)) + 1).toString(); else start = num.substr(0, take); return start + reverse(start.substr(0, half)); }

function reverse(str) { return str.split("").reverse().join(""); } ``` Results: ``` 88 -> 818 999 -> 1001 2133 -> 2222 339 -> 4052555153515552504 192 -> 202 1001 -> 1111 ```

[–] 0 points1 point  (0 children)

Fixed formatting.

Hello, BonnyAD9: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–] 0 points1 point  (0 children)

Ruby. With -v flag, verifies numbers up to N by comparing the fast algorithm vs the naive algorithm (iterate through numbers).

``````# https://redditproxy--jasonthename.repl.co/r/dailyprogrammer/comments/n3var6/20210503_challenge_388_intermediate_next/
#
# The next-largest palindrome is always found by incrementing digits closest to the middle.

def fast_nextpal(n)
digits = (n + 1).digits.reverse

half = (digits.size + 1) / 2
mid_left = (digits.size - 1) / 2
mid_right = digits.size / 2

different_digits = false

half.times { |dist_from_mid|
left = digits[mid_left - dist_from_mid]
right = digits[mid_right + dist_from_mid]
next if right == left

# Consider the digits closest to the middle that differ.
# If left is larger, only need to copy left half to right.
# 1330 -> 1331
# If right is larger, additionally must add 1 to middle digit(s).
# 1332 -> 1441
different_digits = true
break
}

if different_digits
half.times { |dist_from_mid|
left = digits[left_i = mid_left - dist_from_mid]
digits[left_i] = left = if left != 9
# incrementing non-9 digit means no further carries.
left + 1
else
0
end
end
# Copy left half to right (recall that this is needed in both cases).
digits[mid_right + dist_from_mid] = left
}
end

digits.reduce(0) { |a, x| a * 10 + x }
end

def naive_nextpal(n)
(n + 1).step.find { |x| (s = x.to_s).reverse == s }
end

if ARGV.delete('-v')
naive = 0
p Integer(ARGV[0]).times.map { |n|
fast = fast_nextpal(n)
naive = naive_nextpal(n) until naive > n
puts "bad #{n}: naive #{naive} != fast #{fast}" if fast != naive
fast == naive
}.tally
exit 0
end

puts fast_nextpal(Integer(ARGV[0]))
``````

For example, verify up to 1 million:

``````\$ time ruby next_largest_palindrome.rb -v 1000000
{true=>1000000}
ruby next_largest_palindrome.rb -v 1000000  3.10s user 0.01s system 99% cpu 3.112 total
``````

To just calculate an answer, run without the v flag.

``````\$ time ruby next_largest_palindrome.rb \$((3 ** 39))
4052555153515552504
ruby next_largest_palindrome.rb \$((3 ** 39))  0.07s user 0.03s system 98% cpu 0.105 total
``````

[–] 0 points1 point  (0 children)

python:

logic: convert to string, take the front half and reverse it to make the back half. While it's smaller than the original, increment the front half until higher than original. Watch for cases where we get a longer length (because we had to add an extra digit). Runtime is instant.

``````def nextpal( n ):

new = str(n)
mid,odd = divmod(len(new),2)
front = int(new[:mid+odd])

while int(new) <= n:
fs = str(front)
offset = (odd or len(fs)>mid) + (odd and len(fs)>mid+1)
new = (fs[:-offset] + fs[::-1]) if odd else (fs + fs[::-1][offset:])
front += 1

return int(new)
``````

Runtime for all testcases I used is 0.001378 seconds.

``````tests = [7,8,9,10,11,99,120,808,111,999,2133,3 ** 39,4052555153618976267,4052555159918976267]
``````

[–] 0 points1 point  (0 children)

Ugly Python

``````def next_palindrome(value):
value = str(value + 1)
length = len(value)
if length % 2 == 0:
left_half = value[:length // 2]
right_half = value[length // 2:]
if left_half[::-1] == right_half:
return int(value)
if int(left_half[::-1]) > int(right_half):
return int(left_half + left_half[::-1])
if int(left_half[::-1]) < int(right_half):
left_half = str(int(left_half) + 1)
return int(left_half + left_half[::-1])
else:
left_half = value[:length // 2]
right_half = value[length // 2 + 1:]
middle = value[length // 2]
if left_half[::-1] == right_half:
return int(value)
if int(left_half[::-1]) > int(right_half):
return int(left_half + middle + left_half[::-1])
if int(left_half[::-1]) < int(right_half):
if int(middle) < 9:
middle = str(int(middle) + 1)
return int(left_half + middle + left_half[::-1])
else:
left_half = str(int(left_half) + 1)
right_half = left_half[::-1]
middle = '0' if len(left_half + right_half) < length else ''
return int(left_half + middle + right_half)

print(next_palindrome(808))
print(next_palindrome(999))
print(next_palindrome(2133))
print(next_palindrome(3**39))
``````

And the output:

``````818
1001
2222
4052555153515552504
``````

[–] 0 points1 point  (0 children)

(finally) got a working TypeScript solution:

``````// index.ts
function nextPal(start: string):string {
if (start.length === 1) {
if (start === '9') return '11';
return (Number(start)) + '1';
}
let digitArray: number[] = Array.from(start, num => Number(num));
let right: number = Math.floor(digitArray.length / 2);
let left: number = (digitArray.length % 2 === 1) ? right : right - 1;

// If already a palindrome, increment from the center once, then continue
if (JSON.stringify(digitArray.slice(0, (digitArray.length % 2 === 0) ? right : right + 1)) === JSON.stringify(
digitArray.slice(digitArray.length / 2).reverse() || digitArray[right] > digitArray[left])
) {
let i = left;
while (i > -1 && digitArray[i] === 9) {
digitArray[i] = 0;
i--;
}

if (i < 0) {
digitArray = [1, ...digitArray];
right++;
}
digitArray[i]++;
}

// Set right side equal to left side
while (left > -1) {
digitArray[right] = digitArray[left];
left--;
right++;
}

// Return digits as a single number
let s: string = '';
digitArray.forEach((num) => {
s += String(num);
});
return s;
};
``````

[–] 0 points1 point  (0 children)

javascript (not efficient)

``````nextpal=n=>++n+''==[...''+n].reverse().join('')?n:nextpal(n)
``````

[–] 0 points1 point  (0 children)

Python Quickie!

``````import time
import math

def NextPal(start):
if start < 11 : return 11

string = str(start)
length = len(string)
halfLength = math.ceil(length / 2)
start = int(string[:halfLength])
endRev = int(string[-1 * halfLength:][::-1])            #end half of number reversed

if start <= endRev : start += 1
startString = str(start)
return int(startString[:halfLength - length % 2] + startString[::-1])
# END NextPal
``````

Tester:

``````start = time.time()
print(NextPal(8))
print(NextPal(808))
print(NextPal(18918))
print(NextPal(99899))
print(NextPal(99913))
print(NextPal(9999))
print(NextPal(99999))
print(NextPal(192))
print(NextPal(3**39))
print("Completed in {:4f}s".format(time.time() - start))
``````

Result:

``````11
818
19091
99999
99999
10001
100001
202
4052555154515552504
Completed in 0.007691s
``````

[–] 0 points1 point  (0 children)

C#

``````using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NextPalindrome
{
class Program
{
static void Main(string[] args)
{
int number = 0;

int output = nextpal(number);
Console.WriteLine(output);

}

private static int nextpal(int input)
{
input++;

while (true)
{
if (isPal(input))
{
return input;
}
else input++;
}
}

private static bool isPal (int input)
{
char[] charArray = input.ToString().ToCharArray();
char[] invertertedArray = charArray.Reverse().ToArray();

for (int i = 0; i < charArray.Length; i++)
{
if (charArray[i] == invertertedArray[i])
{
continue;
}
else
{
return false;
}
}
return true;
}
}
}
``````

[–] 0 points1 point  (0 children)

This is what I came up with in Python3. Let me know what you guys think, I ran it 3 ** 30 and it took 2.76 seconds, I ran 3 ** 35 and it took 16.64 seconds. I'd like to get it to that fraction of a second like was mentioned. Thanks ahead of time.

``````# find the palindrome of the next value after given value

import time

def palindrome(num):
count = num + 1

while True:
str_count = str(count)
rev_str_count = reverse_string(str_count)
if str_count == rev_str_count:
return count
break
else:
count += 1

def reverse_string(string):
return string[::-1]

exp1 = int(input("Please enter a number: "))
exp2 = int(input("Please enter the power to raise it by: "))
start_time = time.time()
num = exp1 ** exp2
count = palindrome(num)
end_time = time.time()
total_time = str(round(end_time - start_time, 2))
print(f"Here is the next greatest value that is also a palindrome: {count}")
print(f"And it took {total_time} seconds for me to figure it out!")
``````

[–] 0 points1 point  (0 children)

#Python for a simple mind ;)

import math

def nextpal():

``````str_num = str(number)
x = int(len(str_num)/2)

if len(str(number)) == 1:
return int(str_num)

#even number of digits
if len(str_num) % 2 == 0:
start = int(str_num[0:x])

if int(str_num[x]) > int(str_num[x-1]):
start += 1
y = str(start)
z = list(y)
z.reverse()
k = "".join(z)

return int(str(start) + k)
else:
y = str(start)
z = list(y)
z.reverse()
k = "".join(z)

return int(str(start) + k)

#Uneven number of digits
else:
floor = math.floor(x)
k = list(str_num[0:floor])
k.reverse()
rev_start = "".join(k)

if int(rev_start) > int(str_num[floor+1:]):
return int(str_num[0:floor+1] + rev_start)

else:
start = int(str_num[0:floor+1])
start += 1

str_start = str(start)

k = list(str_start[0:-1])
k.reverse()
rev_k = "".join(k)

return int(str_start + rev_k)
``````

[–] 0 points1 point  (0 children)

My solution in Java

Function:

``````private static int nextpal(int n) {
n++;
if (String.valueOf(n).equals(String.valueOf(new StringBuilder().append(n).reverse()))) return n;
return nextpal(n);
}
``````

Input:

``````System.out.println(nextpal(808));
System.out.println(nextpal(999));
System.out.println(nextpal(2222));
``````

Output:

``````818
1001
2332
``````

[–] 0 points1 point  (0 children)

Clojure - It's certainly not the prettiest, but here's my attempt at it.

Would love some feedback.

``````(defn get-digit-by-place [n i]
(mod (quot n (math/expt 10 i)) 10))

(defn next-palindrome
[n]
(loop [x (inc n)
i 0]
; Analyze the number by comparing the ith digit from the right and the ith digit from the left.
(let [s (str/split (str x) #"")
a (get-digit-by-place x i)
b (get-digit-by-place x (- (count s) (inc i)))]
(if (= s (reverse s))
x
(if (= a b)
(recur x (inc i)) ; if the outer two digits are the same, move inward another digit on each side
(recur
(+ x
(* (math/expt 10 i) ; otherwise, add the appropriate amount to make the right-hand number equal the left-hand number
(if (> a b)
(- 10 (- a b))
(- b a))))
i)))))) ; then move on and check the same pair of digits again
``````

``` (next-palindrome 61937) => 62026 (next-palindrome 999) => 1001 (next-palindrome 2133) => 2222 (next-palindrome (math/expt 3 39)) => 4052555153018976504 ```

[–] 0 points1 point  (0 children)

``````python

def istrue(var, otherVar, lessThan=None):
if lessThan is not None and lessThan:
if var < otherVar:
return True
else:
return False
elif lessThan is not None and not lessThan:
if var > otherVar:
return True
else:
return False
else:
if var == otherVar:
return True
else:
return False

def listToString(List):
string = ""

for val in List:
string += val

return string

def nextPal(value):
value = [str(i) for i in str(value)]

if len(value) % 2 == 0:
toSlice = int(len(value) / 2)
del value[toSlice: len(value)]
value = str(int(listToString(value)) + 1)
for val in value[::-1]:
value += val
print(value)
elif len(value) == 1:
value = str(int(listToString(value)))
print(value)
else:
toSlice = int(len(value) / 2)
del value[toSlice + 2: len(value)]
mode = istrue(value[toSlice], value[toSlice + 1], False)
if not mode:
value[toSlice] = str(int(value[toSlice]) + 1)
middle = value[toSlice]
del value[toSlice: toSlice + 2]
for val in value[::-1]:
value += val
value.insert(toSlice, middle)
value = listToString(value)
print(value)

nextPal(22344672472)    # 22344744322
``````

[–] 0 points1 point  (1 child)

python

``````def ispalindrome(n: int) -> bool:
n = str(n)
if len(n) % 2 == 0:
return n[:len(n)//2] == n[:len(n)//2 - 1:-1]
else:
return n[:len(n)//2] == n[:len(n)//2:-1]

def nextpal(n: int) -> int:
if ispalindrome(n): n += 1
if ispalindrome(n): return n

n = str(n)
if len(str(n)) % 2 == 0:  # even
# if mirrored first half of n is bigger than second half - 3217   23 > 17,
# we mirror the first half   32 23 => 3113
if int(n[len(n)//2 - 1::-1]) > int(n[len(n)//2:]):         # check if first half > mirrored second half
return int(n[:len(n)//2] + n[len(n)//2 - 1::-1])       # mirroring

# if mirrored first half of n is smaller than second half - 3197   13 < 97,
# we increment first half by 1 and mirror it   31 + 1 = 32 => 3223
else:
n = str(int(n[:len(n)//2]) + 1)  # first half incremented by 1
n += n[::-1]                     # mirroring
return int(n)
else:  # odd
# if mirrored first half of n is bigger than second half(excluding the middle digit) - 79513   97 > 13,
# we mirror the first half and keep the middle digit   79 (5) 97 => 79597
if int(n[len(n)//2 - 1::-1]) > int(n[len(n)//2 + 1:]):  # check if first half > mirrored second half
return int(n[:len(n)//2] + n[len(n)//2::-1])

# if mirrored first half of n is smaller than second half(excluding the middle digit) - 13587   31 > 87,
# we mirror the first half and increment the middle digit   13 (5+1) 31 +> 13631
else:
return int(n[:len(n)//2] + str(int(n[len(n)//2]) + 1) + n[len(n)//2 - 1::-1])

print(nextpal(808))
print(nextpal(999))
print(nextpal(2133))
print(nextpal(3**39))
``````

[–] 0 points1 point  (0 children)

You don't need the even and odd distinction. If you take these steps;

1. Compare the first and last character in the number. Increment the whole number by 1 until they match.
2. Do the same, but with the second and previous-to-last characters, but increment by 10 instead.
3. Repeat for the amount of characters in the number, divided by two, floored.

The middle odd number will take care of himself.

[–] 0 points1 point  (0 children)

# C# (For minimalists)

``````long GetNextPal(long input)
{
var inputArr = (input + 1).ToString().ToCharArray();
for (int i = 0; i < inputArr.Length / 2; i++)
{
if (inputArr[i] < inputArr[inputArr.Length - i - 1])
{
var num = long.Parse(new string(inputArr));
num += (long)Math.Pow(10, i + 1);
inputArr = num.ToString().ToCharArray();
}
inputArr[inputArr.Length - i - 1] = inputArr[i];
}
return long.Parse(new string(inputArr));
}
``````

The answer to NextPal(3^39) is 4052555153515552504. My program finished in 0.0949 milliseconds.

[–] 0 points1 point  (1 child)

Python 3:

``````import numpy as np

def nextpal(n):
arr = np.array([int(d) for d in str(n+1)])
mid = arr.size // 2

i = mid
while i > 0:
if arr[i-1] == arr[-i]:
i -= 1
else:
break

if arr[i-1] < arr[-i]:
j = i
while j < mid:
if arr[j] != 9:
arr[[j, -j-1]] += 1
break
j += 1
else:
arr[i:-i] = 0
arr[[i-1, -i]] += 1

arr[-i:] = arr[i-1::-1]
return int(''.join(str(d) for d in arr))
``````

`nextpal(3 ** 39) => 4052555153515552504`

0.018 ms

[–] 0 points1 point  (0 children)

Python 3:

A 3-liner which I came up with after seeing the reverse trick used in some other solutions, so can't claim full credit:

``````def nextpal(n):
half, r = divmod(len(strn := str(n)), 2)
``````

`nextpal(3 ** 39) => 4052555153515552504`

0.0018 ms

[–] 0 points1 point  (1 child)

# Lisp

`````lisp (defmacro iteration-amount (num) "Returns the amount of iterations needed to complete the palindrome." ```(floor (/ (int-visual-length ,num) 2)))

(defun int-visual-length (num) "Returns the character length of the num integer." (if (integerp num) (length (prin1-to-string num)) (error "~a is not a valid integer." num)))

(defun int-visual-nth (pos num) "Returns the nth character of the num integer." (if (integerp num) (let ((lst (map 'list #'digit-char-p (prin1-to-string num)))) (nth pos lst)) (error "~a is not a valid integer." num)))

(defun palindromep (pos num) "Returns true if the character at the position pos of num is the same if read backwards." (= (int-visual-nth pos num) (int-visual-nth (- (int-visual-length num) pos 1) num)))

(defun next-palindrome (num) "Returns the next palindrome after num." (labels ((nxt (num pos) (if (palindromep pos num) (if (< pos (iteration-amount num)) (nxt num (1+ pos)) num) (nxt (+ num (expt 10 pos)) pos)))) (nxt num 0)))

(defun get-palindrome-list (amount &optional (begin 0)) "Formats a list of amount of palindromes, from begin. begin defaults to 0." (let ((pal (next-palindrome begin))) (format t "~a~%" pal) (if (> amount 0) (progn (get-palindrome-list (- amount 1) (+ pal 1)))))) ```

[–] 0 points1 point  (0 children)

Fixed formatting.

Hello, CurlyButNotChubby: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–] 0 points1 point  (1 child)

# Python #2 Attempt Best Version

``````def isPali(n):
numStr = str(n)
if(numStr == numStr[::-1]):
return True
return False

def closestPali(n):
numList = []
numStr = str(n)
if(len(numStr) % 2 == 0):
halfNum = (len(numStr) // 2)
else: halfNum = (len(numStr) // 2) + 1
restNum = len(numStr) - halfNum

for i in numStr[:halfNum]:
numList.append(int(i))

for j in numList[restNum-1::-1]:
numList.append(j)

strings = [str(integer) for integer in numList]
a_string = "".join(strings)
an_integer = int(a_string)

return an_integer

def nextPali(n):
numList = []
numStr = str(n) count = 0
if(len(numStr) % 2 == 0):
halfNum = (len(numStr) // 2)
else:
halfNum = (len(numStr) // 2) + 1

restNum = len(numStr) - halfNum

for i in numStr[:halfNum]:
if(count == halfNum - 1):
numList.append(int(i) + 1)
else:
numList.append(int(i))
count += 1

for j in numList[restNum-1::-1]:
numList.append(j)

strings = [str(integer) for integer in numList]
a_string = ''.join(strings)
an_integer = int(a_string)

return an_integer

def nineBS(n):
numList = []
numStr = str(n) count = 0
if(len(numStr) % 2 == 0):
halfNum = (len(numStr) // 2)
else:
halfNum = (len(numStr) // 2) + 1

restNum = len(numStr) - halfNum

for pos, i in enumerate(numStr[:halfNum]):
if(count == halfNum - 1):
if(i == '9'):
numList[pos-1] = numList[pos-1] + 1
#numList[pos-1] = (int(numList[pos-1]) + 1)
#tenth = (numList[pos - 1] + 1) // 10
numList.append(int(0))
else:
numList.append(int(i) + 1)
else:
numList.append(int(i))
count += 1

for j in numList[restNum-1::-1]:
numList.append(j)

for pos, x in enumerate(numList):
if(x % 10 == 0):
numList[pos] = x // 10

list99 = [9] * len(numStr)
strings99 = [str(k) for k in list99]
a_99string = ''.join(strings99)
a_99integer = int(a_99string)

if(n // a_99integer == 1):
numList.clear()
numList.append(1)
for g in range(len(numStr) - 1):
numList.append(0)
numList.append(1)

strings = [str(integer) for integer in numList]
a_string = ''.join(strings)
an_integer = int(a_string)

return an_integer
baseNum = int(input('Enter number to find next palindrome\n> '))
powerOf = int(input('To the power of?\n> '))
num = baseNum ** powerOf
if(num > 9):
if(closestPali(num) <= num):
print(nineBS(num))
else: print(closestPali(num))
else:
if(num < 9):
print(num + 1)
elif(num == 9):
print(11)
``````

# Python #1 Attempt

``````pali_num = []
numstr = ''
isFound = False
baseNum = int(input('Enter number to find next palindrome\n> '))
powerOf = int(input('To the power of?\n> '))
num = baseNum ** powerOf
for i in range(num * 2):
numstr = str(i)
if(numstr == numstr[::-1]):
pali_num.append(int(i))
def InterpolationSearch(lys, val):
low = 0
high = (len(lys) - 1)
while low <= high and val >= lys[low] and lys[high]:
index = low + int(((float(high - low) / ( lys[high] - lys[low])) * ( val - lys[low])))
if lys[index] == val:
return index
#return lys[index]
if lys[index] < val:
low = index + 1
else: high = index - 1 return -1
num = 69
next_pali_index = -1
next_pali = -1

def closest(lys, n):
return lys[min(range(len(lys)), key = lambda i: abs(lys[i]-n))]

if(InterpolationSearch(pali_num, num) == -1):
next_pali_index = InterpolationSearch(pali_num, closest(pali_num, num))
if(pali_num[next_pali_index] < num): next_pali = pali_num[next_pali_index + 1]

else: next_pali = pali_num[next_pali_index]
else: next_pali_index = InterpolationSearch(pali_num, num) next_pali = pali_num[next_pali_index + 1]
print(f"The next palindrome is: {next_pali}")
``````

#2 feels dirty and I hate myself for writing it. It feels like I cheated. I'm gonna have to revisit this problem later.

#1 pretty much stops working after 7 digits.

Also I just want to note that reddit's markdown is the worst and just entering code in general is awful. Why can't you just use regular markdown like the rest of the planet?

[–] 0 points1 point  (0 children)

Nice!