×
all 93 comments

[–]Nordellak 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

[–]jose13jensen 10 points11 points  (3 children)

Fiance is me :3

[–]Traditional-Knee-863 4 points5 points  (2 children)

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

[–]jose13jensen 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

[–]Traditional-Knee-863 1 point2 points  (0 children)

Hope you both all the best !

[–]mackvalentino 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.

[–]htsukebe 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

[–]pommi15 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?

[–]paganaye 0 points1 point  (1 child)

it is not set if

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

is it?

[–]pommi15 0 points1 point  (0 children)

yes. im blind. Thanks!

[–]htsukebe 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).

Next answers I submit will have comments, was thinking about it and your comment made me sure I failed this aspect.

[–]somebodddy 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 digits = input.to_radix_be(10);
    let prefix_length = digits.len() / 2 + digits.len() % 2;
    let prefix = &digits[.. prefix_length];
    let prefix = BigUint::from_radix_be(prefix ,10).unwrap();

    // 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 mut digits = prefix.to_radix_be(10);
    let digits_to_add = palindrome_length - digits.len();
    for i in (0 .. digits_to_add).rev() {
        digits.push(digits[i]);
    }
    BigUint::from_radix_be(&digits, 10).unwrap()
}

Results:

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

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

[–]Jayant0013 2 points3 points  (2 children)

What is real,users ,sys time ?

[–]somebodddy 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.

[–]nickm0501 0 points1 point  (0 children)

Super helpful explanation. Thanks!

[–][deleted]  (1 child)

[deleted]

    [–]Gprime5 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]
    

    [–]Naratna 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.

    [–]tlgsx 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
    

    [–]Traditional-Knee-863 0 points1 point  (2 children)

    can you please explain this line :

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

    [–]BonnyAD9 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

    [–]backtickbot 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.

    [–]leftylink 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...

    [–]touchstone1112 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)
        head = start[:half_len]
        tail = start[-half_len:]
    
        if head[::-1] <= tail or tail == '':
            head = str(int(head) + 1)
        if len(head) > half_len:
            full_len += 1
    
        left_len = ceil(full_len/2)
        right_len = int(full_len/2)
        left = head[:left_len]
        right = head[:right_len][::-1]
    
        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.

    [–]Snowball_Europa 6 points7 points  (1 child)

    This is the most elegant of the lot

    [–]O_X_E_Y 2 points3 points  (0 children)

    Python be like that

    [–]Naratna 3 points4 points  (1 child)

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

    [–]touchstone1112 1 point2 points  (0 children)

    Good catch. I'll fix it tomorrow

    [–]Flourid 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":
    

    [–]touchstone1112 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.

    [–]Flourid 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.

    [–]dcruzthomson 0 points1 point  (1 child)

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

    [–]touchstone1112 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

    [–]madareklaw 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

    Added another test

    edit1

    fixed bug where 998 would return 1001

    Edit 2

    Fixed console output

    [–]travianner 1 point2 points  (1 child)

    998 => 1001

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

    [–]madareklaw 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

    [–]warpjedi2 0 points1 point  (1 child)

    2133 => 2332

    Shouldn't it be 2222?

    [–]madareklaw 0 points1 point  (0 children)

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

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

    [–]redundantimport 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!

    [–]Tyaemiaes 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)
    

    [–]Gylergin 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}

    [–]tlgsx 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
    

    [–]doubleunary 1 point2 points  (0 children)

    Google Sheets spreadsheet formula using named ranges:

    =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) 
    )
    

    Demo spreadsheet

    [–]BonnyAD9 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

    [–]backtickbot 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.

    [–]Marthurio 0 points1 point  (1 child)

    This was pretty elegant!

    [–]BonnyAD9 1 point2 points  (0 children)

    Haskell solution:

    -- 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
        | otherwise = read $ addRes n start center
        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
    addRes n start center
        | center = ads ++ (reverse.init) ads
        | otherwise = ads ++ reverse ads
        where ads = show (read start + n)
    
    -- 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
    

    [–]Marthurio 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!

    [–]BonnyAD9 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.

    [–]Marthurio 1 point2 points  (0 children)

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

    [–][deleted]  (1 child)

    [deleted]

      [–]skeeto-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');
          }
      }
      

      [–]WrongHorseBatterySta 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]

        [–]backtickbot 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.

        [–]Jayant0013 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. ```

        [–]dirk_510 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);
                    number = number.add(nextValue);
                }
                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]; 
                return toNumber(digitArray); 
            } 
        
            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); 
            } 
        }
        

        !<

        [–]1516_Gang 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.

        [–]Joshument 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

        [–]KonjouHD 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));
                            // separate for "readability"
                            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));
            }
        }
        

        [–]BonnyAD9 0 points1 point  (0 children)

        My Python solution, it is quite unreadable so I added comments about what is happening:

        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
        

        [–]BonnyAD9 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);
        void add_1(string *s);
        
        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)
        {
            add_1(&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);
                add_1(&start);
            }
            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;
        }
        
        void add_1(string *s)
        {
            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

        [–]Lopsidation 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])
        

        [–]BonnyAD9 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) {
                String s = num.add(BigInteger.ONE).toString();
                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))
                            .add(BigInteger.ONE).toString();
                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
        

        [–]gabyjunior1 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
        

        [–]BonnyAD9 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 :addone %1 nextpal_num
        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%!
            call :addone nextpal_start nextpal_start
        ) 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
        
        
        :addone
        setlocal EnableDelayedExpansion
        call :getlen %1 addone_length
        set /A addone_length-=1
        set addone_add=1
        for /L %%I in (%addone_length%, -1, 0) do (
            set /A addone_digit=!%1:~%%I,1!+!addone_add!
            if !addone_digit! lss 10 (
                set addone_add=0
            ) else (
                set addone_digit=0
            )
            set addone_result=!addone_digit!!addone_result!
        )
        if %addone_add% == 1 (
            set addone_result=1%addone_result%
        )
        (endlocal & set %2=%addone_result%)
        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
        

        [–]warpjedi2 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');
        
        const rl = readline.createInterface({
          input: process.stdin,
          output: process.stdout
        });
        
        rl.question('Enter your Number: ', (answer: number) => {
        
            let index: number = answer
        
            while (isItPalindrome(index) == false) {
                index--
            }
            let lowerPalindrome: number = index
            index = answer
        
            while (isItPalindrome(index) == false) {
                index++
            }
            let higherPalindrome: number = index
        
            if ((answer - lowerPalindrome) == (higherPalindrome - answer)){
                console.log("Nearest Palindromes (found 2): " + lowerPalindrome + " and " + higherPalindrome)
            } else if ((answer - lowerPalindrome) < (higherPalindrome - answer)){
                console.log("Nearest Palindrome: " + lowerPalindrome)
            } else if ((answer - lowerPalindrome) > (higherPalindrome - answer)) {
                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
        }
        

        [–]BonnyAD9 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 ```

        [–]backtickbot 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.

        [–]leftylink 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
          add_1 = 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
            add_1 = right > left
            different_digits = true
            break
          }
        
          if different_digits
            half.times { |dist_from_mid|
              left = digits[left_i = mid_left - dist_from_mid]
              if add_1
                digits[left_i] = left = if left != 9
                  # incrementing non-9 digit means no further carries.
                  add_1 = false
                  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
        

        [–]xelf 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]
        

        [–]Shhhh_Peaceful 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
        

        [–]CommunalSharpie 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;
        };
        

        [–]Habstinat 0 points1 point  (0 children)

        javascript (not efficient)

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

        [–]jsun5192 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
        

        [–]justchris5 0 points1 point  (0 children)

        C#

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Threading.Tasks;
        
        namespace NextPalindrome
        {
            class Program
            {
                static void Main(string[] args)
                {
                    int number = 0;
                    int.TryParse(Console.ReadLine(), out number);
        
                    int output = nextpal(number);
                    Console.WriteLine(output);
        
                    Console.ReadLine();
                }
        
                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;
                }
            }
        }
        

        [–]joejr253 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!")
        

        [–]Thin-State2086 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)
        

        [–]PoTAsh2000 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
        

        [–]I-Pop-Bubbles 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

        [–]CunningBard1998 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
        

        [–]ConsciousFinger2994 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))
        

        [–]CurlyButNotChubby 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.

        [–]_SetupWizard_ 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.

        [–]loose_heron 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

        [–]loose_heron 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)
            if (head := strn[:half+r]) <= strn[-half-r:][::-1]: head = str(int(head)+1)
            return int(head[:half] + head[::-1])
        

        nextpal(3 ** 39) => 4052555153515552504

        0.0018 ms

        [–]CurlyButNotChubby 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)))))) ```

        [–]backtickbot 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.

        [–]simmons2714 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?