Find the closest palindromic number

23

3

Given a number N, output/return X so that N+X is a palindrome, where |X| has to be as small as possible.

Palindrome: A number is a palindrome, if its sequence of digits is the same when reading them from left to right as when reading from right to left.
95359 and 6548456 are symmetric, 123 and 2424 are not. Numbers with leading zeros such as 020 are not a palindrome.

Input is a positive integer smaller than 1015. Read it from stdin, as a method-parameter, whatever.

Output has to be an integer (positive or negative) and ought to be 0 if the input is already a palindrom. You may write your output to stdout, return it from a function or whatever you like. If there are 2 numbers (e.g. 2 and -2) that satisfy the requirements, output only one of them.

Examples:

Input             Output
3                 0
234               -2
1299931           -10
126               5 or -5 (only one of them)

CommonGuy

Posted 2014-08-27T13:28:53.350

Reputation: 4 684

Presumably if a number is halfway between the two nearest palindromes, either is an acceptable output? E.g. for N=10 the output can be X=-1 or X=1? – Peter Taylor – 2014-08-27T13:45:52.950

@PeterTaylor Yes, it just has to be as small as possible. – CommonGuy – 2014-08-27T13:47:12.440

Answers

9

Pyth, 26 20

Lnb_bWP`+QZ=Z-g0ZZ)Z

Updated to meet the new rules.

The program runs in an infinite loop which tests every possible increment, in the order 0, -1, 1, -2, -2 ...

Explanation:

Q=eval(input())     implicit
Z=0                 implicit
Lnb_b               def P(b): return b != rev(b)
WP`+QZ              while P(repr(Q+Z)):
=Z-g0ZZ             Z=(0>=Z)-Z
)                   <end while>
Z                   print(Z)

Example run:

python3 pyth.py programs/palin.pyth <<< 965376457643450
-2969881

This took 23 seconds.


Bonus solution, same character count:

Wn`+QZ_`+QZ=Z-g0ZZ)Z

isaacg

Posted 2014-08-27T13:28:53.350

Reputation: 39 268

Just to let you know, the rules changed to finding the nearest palindrome (in either direction). But I guess since you posted before that rule change there's no obligation for you to fix it. – Martin Ender – 2014-08-27T14:12:33.390

Might it save chars to loop Z through [0, 1, -1, 2, -2, ...] by an update Z=-Z+(Z<0)? – xnor – 2014-08-27T20:37:23.250

Yep - I thought of that independently. – isaacg – 2014-08-27T23:31:43.117

@xnor Added. Filler. – isaacg – 2014-08-27T23:36:39.910

Ok, cool. Have you also looked into putting the negation of the condition into the while? And maybe saving a repr by applying it to the input to P? – xnor – 2014-08-27T23:40:36.550

@xnor Perfect timing - just added those. – isaacg – 2014-08-27T23:48:57.133

One last thing I can think of: can the lambda-expression for P go in place of P? – xnor – 2014-08-28T00:26:23.263

@xnor No, there aren't lambda expressions in Pyth. L is really just a shorthand way to define functions. – isaacg – 2014-08-28T00:38:29.420

Ah, I see. And putting the function expression gives the same length because the input needs to be written twice. Any chance then it would help to loop through Q+Z instead, updating by flipping around Q? Unfortunately you need to output Z though. – xnor – 2014-08-28T00:56:41.770

@xnor Right, and also it's a lot easier to move Z near 0 than Q+Z near Q. – isaacg – 2014-08-28T00:58:24.407

I really have to learn your language... The trick for updating Z is nice; I've borrowed it. I don't understand the Z=(Z>=0)-Z part though; this should result in 0 → 1 → 0 → 1 → …. Z=(Z<1)-Z would work as you explained. – Dennis – 2014-08-28T02:58:40.677

Your first solution doesn't work for me; it hangs for every input. The bonus solution works just fine. – Dennis – 2014-08-28T03:04:20.583

@Dennis Try updating the version of Pyth (git pull), I changed some things involving L recently. Also, you're right, there's a typo in my explanation. I'm using g0Z, which is 0>=Z, not Z>=0. I'll fix that. – isaacg – 2014-08-28T19:20:48.777

7

Ruby, 111 84 bytes

i=$*[j=-1].to_i
r=->j{s=(i+j).to_s
abort(j.to_s)if s==s.reverse}
loop{r[j+=1]
r[-j]}

Takes the number as its only command-line argument.

Martin Ender

Posted 2014-08-27T13:28:53.350

Reputation: 184 808

How about this website?

– CommonGuy – 2014-08-27T13:59:55.267

@Manu Thanks didn't know that one! My submission works as far as I can tell. – Martin Ender – 2014-08-27T14:01:41.173

6

CJam, 34 29 25 bytes

q~:I!{:R1<R-RI+`_W%=!}g;R

Try it online.

Examples

$ cjam palfind.cjam <<< 120; echo
1
$ cjam palfind.cjam <<< 121; echo
0
$ cjam palfind.cjam <<< 122; echo
-1

How it works

q~:I    " Read from STDIN, evaluate and save the result in “I”.                           ";
!       " Compute the logical NOT (0 since the integer is positive).                      ";
{       "                                                                                 ";
  :R    " Save the topmost integer in “R”.                                                ";
  1<R-  " Compute (R < 1) - R. This produces the sequence 0 → 1 → -1 → 2 → -2 → … .       ";
  RI+   " Push I + R.                                                                     ";
  `_    " Cast to string and push a copy.                                                 ";
  W%=!  " Check if the reversed copy matches the original.                                ";
}g      " If it doesn't, repeat the loop.                                                 ";
;R      " Discard the integer on the stack and push “R”.                                  ";

Dennis

Posted 2014-08-27T13:28:53.350

Reputation: 196 637

5

Haskell - 62

f n=[x-n|x<-[0..]>>= \v->[n+v,n-v],show x==(reverse.show)x]!!0

Save it to a file named golf.hs and then test it with ghci:

*Main> :l golf
[1 of 1] Compiling Main             ( golf.hs, interpreted )
Ok, modules loaded: Main.
*Main> map f [1000..1050]
[-1,0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31,-32,-33,-34,-35,-36,-37,-38,-39,-40,-41,-42,-43,-44,-45,-46,-47,-48,-49]
*Main> 

Ray

Posted 2014-08-27T13:28:53.350

Reputation: 1 946

how about writing x<-[0..]>>=(\v->[n+v,n-v]) ? It is shorter and it makes it a one-liner – proud haskeller – 2014-08-28T07:43:37.483

@proudhaskeller Thanks! Very elegant trick with the list monad. – Ray – 2014-08-28T07:50:29.223

4

05AB1E, 15 14 bytes (-1 Thanks to Emigna)

2äнsgÈi∞ë.∞}s-

Try it online!


Method:

  • Take the first half of the number.
  • Mirror it intersected if odd, non-intersected if even.
  • Difference.

Magic Octopus Urn

Posted 2014-08-27T13:28:53.350

Reputation: 19 422

I think you can use 2äн instead of g;î£. – Emigna – 2017-12-04T14:48:02.893

.∞ can be û to save a byte. Minor alternative without the if-else: 2äнD∞sû‚IgèI- – Kevin Cruijssen – 2020-02-18T16:52:21.123

4

Python 2.7, 98, 81

Creates a palindrome from the input number, then subtracts that from the input to find the delta.

def f(n):
    m=map(int,str(n));l=len(m)/2;m[-l:]=m[l-1::-1];return int(`m`[1::3])-n

usage:

print f(3)          # 0
print f(234)        # -2
print f(2342)       # -10
print f(129931)     # -10
print f(100000)     # 1

ungolfed and annotated:

def f(n):                      # take a integer n
    m=map(int,str(n));         # convert n into array of ints
    l=len(m)/2;                # get half the length of the array of ints
    m[-l:]=m[l-1::-1];         # replace the last elements with the first elements reversed
    return int(`m`[1::3])-n    # convert array of ints backinto single int and subtract the original number to find the delta

Moop

Posted 2014-08-27T13:28:53.350

Reputation: 723

For me it the only one that not has make sums +1 and difference -1 instead work on string break in 2 parts , and this is ok – RosLuP – 2017-11-20T19:31:45.070

This doesn't give the smallest delta. f(19) = -8 (palindrome 11), where it should be +3 to make 22. – Geobits – 2014-08-27T18:31:28.663

@Geobits Yes, the 10-100 values will give me a problem with this approach – Moop – 2014-08-27T18:47:01.397

It's not just those. Similarly, 199999 gives -8 instead of 3, 9911 gives 88 instead of -22. Just reversing the first digits doesn't work to get the smallest delta in a lot of cases. – Geobits – 2014-08-27T18:52:35.083

well i wouldn't say a lot of cases, i bet 99.9% of cases it works for. But yes, it needs to work for 100% of cases – Moop – 2014-08-27T18:55:14.167

@Geobits. Sure, so 27% error rate there. But when you get to the 100000000s the error rate drops considerably. It would be interesting to calculate the actual error rate. – Moop – 2014-08-27T19:08:00.750

4

Perl 5, 93 89 88 87 75 63 44

$/=($/<1)-$/while$_+$/-reverse$_+$/;$_=$/+0

Ungolfed:

while($input + $adjustment - reverse($input + $adjustment)) {
    $adjustment = ($adjustment < 1) - $adjustment;   
}
$input = $adjustment + 0;  ## gives 0 if $adj is undefined (when $input is a palindrome)
print $input;  ## implicit

Thanks to Dennis's suggestions, got it down to 43 + -p = 44

user0721090601

Posted 2014-08-27T13:28:53.350

Reputation: 928

1>

  • -$a is shorter than $a*-1. 2. If you use ($a<1), there's no need for ? :$a++. 3. If you use the -p switch, $_=<> and print$_ is implicit, so you can drop the first statement and change the last to $_=$a+0.
  • < – Dennis – 2014-08-28T21:55:04.560

    @Dennis Nice finds. This is only my second attempt at code golf, so appreciate the advice! – user0721090601 – 2014-08-28T22:02:04.933

    It's customary to count the -p switch as one extra byte, but you can get it back by using ($a<1)-$a instead of -$a+($a<1). – Dennis – 2014-08-28T22:52:01.653

    @Dennis I though about using that method based on your answer above, but the gain gets lost because it requires a space before while – user0721090601 – 2014-08-28T22:56:54.093

    If you use $/ instead of $a, it will work. – Dennis – 2014-08-28T23:01:28.750

    Duh. I'm going to go put my dunce cap on now. – user0721090601 – 2014-08-28T23:35:53.037

    3

    Java : 127 109

    Basic iteration, checking both negative and positive before moving to the next candidate.

    int p(long n){int i=0;for(;!(n+i+"").equals(new StringBuilder(n+i+"").reverse()+"");i=i<1?-i+1:-i);return i;}
    

    For input 123456789012345, it returns -1358024, to equal palindrome 123456787654321.

    Line breaks:

    int p(long n){
        int i=0;
        for(;!(n+i+"").equals(new StringBuilder(n+i+"").reverse()+"");i=i<1?-i+1:-i);
        return i;
    }   
    

    Geobits

    Posted 2014-08-27T13:28:53.350

    Reputation: 19 061

    Does n+i+"" work and save the brackets? I think that the precedence should be correct. – Peter Taylor – 2014-08-27T14:45:30.547

    @PeterTaylor Yep, and got another few from toString(). Thanks :) – Geobits – 2014-08-27T14:53:04.040

    1Can I steal that sweet i=i<1?-i+1:-i? I shall call it "indecrement". – Jacob – 2014-08-28T09:19:06.523

    @Jacob Go for it ;) – Geobits – 2014-08-28T12:32:10.330

    3

    Clojure, 92

    Takes the first from a lazy for-sequence that works from 0 out and only includes values that make palindromes:

    (defn p[x](first(for[i(range)j[1 -1]k[(* i j)]s[(str(+ x k))]:when(=(seq s)(reverse s))]k)))
    

    REPL-LPER session:

    golf-flog> (p 3)
    0
    golf-flog> (p 10)
    1
    golf-flog> (p 234)
    -2
    golf-flog> (p 1299931)
    -10
    golf-flog> (p (bigint 1e15))
    1
    

    YosemiteMark

    Posted 2014-08-27T13:28:53.350

    Reputation: 213

    2

    Javascript 86

    n=>{s=(n+'').split('');for(i=0,j=s.length-1;i<j;i++,j--)s[j]=s[i];return s.join('')-n}
    

    This is my first codegolf challenge. Hope this solution is acceptable.

    ungolfed: n => { s = (n + '').split(''); for (i = 0, j = s.length - 1; i < j; i++,j--) s[j] = s[i]; return s.join('') - n } Explanation:
    Convert input n to String and split.
    Iterate over both sides of the resulting array and copy digit on s[i] to s[j] until i < j. This will result in our desired palindrome.
    Join array back together and subtract n to get x

    Beldraith

    Posted 2014-08-27T13:28:53.350

    Reputation: 21

    Welcome to PPCG! This answer has the right structure (function submissions normally work best in JavaScript), and seems to give the right answers too. Your post might be improved via an explanation of why this algorithm works (it's not obvious to me why it does), but it's fine at the moment. – None – 2017-02-23T12:45:34.273

    Thanks, ive added a small explanation and an ungolfed version – Beldraith – 2017-02-23T13:19:04.217

    you can change s=(n+'').split('') to s=[...(n+'')]. to shave off 5 bytes – Brian H. – 2017-11-21T12:06:15.957

    I was thinking the same way, but 19 seems to be the first counterexample: f(19)=3 because 22 is closest palindromic, but the function returns -8 for converting 19 into 11. btw [...n+''] will also work for an extra -2 bytes – Shieru Asakoto – 2017-12-07T01:42:01.513

    2

    JavaScript (ES6), 84 bytes

    n=>[...(''+n)].reduce((p,c,i,s,m=s.length-1)=>i<m/2?p+(c-s[m-i])*Math.pow(10,i):p,0)
    

    My first golf challenge! I know the shorter and more elegant solution has already been posted by @Brian H., but this is another approach.

    Test Code

    const t =
    n=>[...(''+n)].reduce((p,c,i,s,m=s.length-1)=>i<m/2?p+(c-s[m-i])*Math.pow(10,i):p,0)
    ;
    
    console.log('t(3) =', t(3)); // expected: 0
    console.log('t(234) =', t(234)); // expected: -2
    console.log('t(1299931) =', t(1299931)); // expected: -10
    console.log('t(126) =', t(126)); // expected: -5

    yetirs

    Posted 2014-08-27T13:28:53.350

    Reputation: 31

    1Welcome to PPCG! – Steadybox – 2017-11-23T21:51:39.403

    2

    Brachylog, 8 bytes

    ;.≜+A↔A∧
    

    Try it online!

    The label predicate is vital here, because by using it on the output before anything else happens (although it's really being invoked on the list containing the input and the output), its absolute value is minimized, because instead of doing anything smarter based on the constraints the program guesses every integer starting from 0 until it can find one that works. If is omitted, it dawns on the program that 0 is a very nice palindrome, and it will always output the negative of the input.

                The input
    ;  +        plus
     .          the output
      ≜         which is instantiated immediately
        A       is A
         ↔      which reversed
          A     is still A
           ∧    but isn't necessarily the output.
    

    Unrelated String

    Posted 2014-08-27T13:28:53.350

    Reputation: 5 300

    2

    JavaScript, 175 136 117

    Straightforward. p returns true if a given number is palindrome, f searches the nearest.

    EDIT: I also golfed it a little bit more thanks to the sweet "indecrement" trick by Geobits in the Java answer here.

    p=function(n){return (s=''+n).split('').reverse().join('')==s}
    f=function(n){for(i=0;!p(n+i);i=i<1?-i+1:-i);return i}
    

    Usage:

    f(3)
    f(234)
    f(1299931)
    

    Jacob

    Posted 2014-08-27T13:28:53.350

    Reputation: 1 582

    1Sorry for the 3-year delay, but golfed to 68 in ES6: s=>{for(i=0;[...s+i+""].reverse().join``!=s+i;i=i<0?-i:~i);r‌​eturn i}. Stack-overflow prone 61: f=(s,i=0)=>[...s+i+""].reverse().join``==s+i?i:f(s,i<0?-i:~i‌​) ;) – Shieru Asakoto – 2017-12-07T02:20:19.207

    104 in ES6: p=n=>[...s=''+n].reverse().join('')==s f=n=>{r=t=0;while(!(p(n+r++)||p(n+t--)));return p(n+r-1)?r-1:t+1} :) – William Barbosa – 2014-08-27T19:09:05.030

    1I bet it is. function and return are terribly long reserved-words... – Jacob – 2014-08-27T19:12:17.740

    2

    J - 49 char

    A function mapping integers to integers.

    ((0{g#f)>:@]^:(+:/@g=.(-:|.)@":@+f=._1 1*])^:_&0)
    

    Here's how you might build to this result, in three parts. This is the display of the J REPL: indented lines are user input and outdented ones are REPL output. And yes, J spells the negative sign with an underscore _.

       236 (_1 1*]) 4                          NB. -ve and +ve of right arg
    _4 4
       236 (f=._1 1*]) 4                       NB. name it f
    _4 4
       236 (+f=._1 1*]) 4                      NB. add left to each
    232 240
       236 (":@+f=._1 1*]) 4                   NB. conv each to string
    232
    240
       236 ((-:|.)@":@+f=._1 1*]) 4            NB. palindrome? on each
    1 0
       236 (g=.(-:|.)@":@+f=._1 1*]) 4         NB. name it g
    1 0
       236 (+:/@g=.(-:|.)@":@+f=._1 1*]) 4     NB. logical NOR (result 1 if both=0)
    0
       palin =: (+:/@g=.(-:|.)@":@+f=._1 1*])
    
    
       236 (>:@]) 0                            NB. increment right
    1
       236 (>:@]^:2) 0                         NB. functional power
    2
       236 (>:@]^:(236 palin 3)) 3             NB. power 1 if no palindromes
    4
       236 (>:@]^:(236 palin 4)) 4             NB. power 0 if has palindrome
    4
       236 (>:@]^:palin) 4                     NB. syntactic sugar
    4
       236 (>:@]^:palin^:_) 0                  NB. increment until palindrome, start with 0
    4
       (>:@]^:(+:/@g=.(-:|.)@":@+f=._1 1*])^:_&0) 236    NB. bind 0
    4
       delta =: >:@]^:(+:/@g=.(-:|.)@":@+f=._1 1*])^:_&0
    
    
       ((f) delta) 236       NB. f=: -ve and +ve
    _4 4
       ((g) delta) 236       NB. g=: which are palindromes
    1 0
       ((g#f) delta) 236     NB. select the palindromes
    _4
       ((g#f) delta) 126     NB. what if both are equal?
    _5 5
       ((0{g#f) delta) 126   NB. take the first element
    _5
       ((0{g#f)>:@]^:(+:/@g=.(-:|.)@":@+f=._1 1*])^:_&0) 236   NB. it works!
    _4
    

    Examples:

       pal =: ((0{g#f)>:@]^:(+:/@g=.(-:|.)@":@+f=._1 1*])^:_&0)
       pal 3
    0
       pal every 234 1299931 126
    _2 _10 _5
       pal 2424
    18
       2424 + pal 2424
    2442
    

    You can also make the golf prefer the positive solution over the negative when they're equal, by changing _1 1 to 1 _1.

    algorithmshark

    Posted 2014-08-27T13:28:53.350

    Reputation: 8 144

    1

    PHP, 56 bytes

    for(;strrev($i+$n=$argv[1])-$n-$i;$i=($i<1)-$i);echo+$i;
    

    takes input from command line argument; run with -nr.

    Titus

    Posted 2014-08-27T13:28:53.350

    Reputation: 13 814

    You could save 3 bytes by using $argn with -F in command line instead of $argv[1] and using input instead of adding an argument. – Kaddath – 2020-02-18T16:11:46.750

    1

    javascript 68 bytes

    (n,s=[...(''+n)],j=s.length)=>s.map((v,i,)=>i>--j?s[j]:v).join('')-n
    

    HUGE props to @Beldraith for the algorithm, i'm posting this as an answer though, because it took me quite the time to get it to work in a single statement.

    Any tips are welcome ;)

    ungolfed

    (
        n, // input
        s=[...(''+n)], // input split to array of chars
        j=s.length, // highest available index in s
    )=> 
    s.map( // this will return a new array, without modifying s
        (
            v, // value of current iteration
            i, // index of current iteration
        )=> i > --j ? s[j] : v
    ).join('') - n
    

    Brian H.

    Posted 2014-08-27T13:28:53.350

    Reputation: 513

    @Beldraith hope you dont mind me porting your answer to a single statement function, i had a blast doing so :D – Brian H. – 2017-11-21T13:21:54.317

    Golfable to 63: (n,s=[...n+''],j=s.length)=>s.map((v,i)=>i>--j?s[j]:v).join``-n, but also a non-obvious counterexample (19) exists ;) – Shieru Asakoto – 2017-12-08T03:03:48.670

    ouch, it's not just 19, it's any number that ends with a 9 and should get a positive result – Brian H. – 2017-12-11T10:02:26.037

    1

    Groovy - 131 111 107 chars

    Golfed:

    n=args[0] as long;a=n;b=n;f={if("$it"=="$it".reverse()){println it-n;System.exit 0}};while(1){f a++;f b--}
    

    sample runs:

    bash-2.02$ groovy P.groovy  0
    0
    bash-2.02$ groovy P.groovy  234
    -2
    bash-2.02$ groovy P.groovy  1299931
    -10
    bash-2.02$ groovy P.groovy  123456789012345
    -1358024
    

    Ungolfed:

    n=args[0] as long
    a=n
    b=n
    f={ if("$it"=="$it".reverse()) {
           println it-n
           System.exit 0
        }
    }
    
    while(1) {
        f a++
        f b--
    }
    

    Michael Easter

    Posted 2014-08-27T13:28:53.350

    Reputation: 585

    1

    Python 2 - 76

    i=input()
    print sorted([r-i for r in range(2*i)if`r`==`r`[::-1]],key=abs)[0]
    

    Gets the input number and generates a list of the differences between the input and every number between 0 and 2*i only if the number is palindromic.

    It then sorts the list by absolute value and prints the first element.

    BeetDemGuise

    Posted 2014-08-27T13:28:53.350

    Reputation: 442

    I don't think range(2*i) will work for large inputs. – Moop – 2014-08-27T20:13:07.743

    You can use min with a keyword argument rather than sorting. – xnor – 2014-08-27T21:00:26.550

    To use ranges that long, you need to switch to xrange, which is a generator, and min, which short-circuits, to avoid overrunning your memory. – isaacg – 2014-08-28T01:56:25.867

    1

    C++ 289

    Function P checks for palindromes using <algorithm> method.

    Ungolfed:

    bool P(int32_t i)
    {
    string a,b;
    stringstream ss;
    ss<<i;
    ss>>a;
    b=a;
    reverse_copy(b.begin(),b.end(),b.begin());
    int k=a.compare(b);
    return (k==0);
    }
    int main()
    {
    int32_t n; cin>>n;
    int32_t x=0,y=n,z=n,ans=x;
    while(1)
    {
    if(P(y)){ans=x; break;}
    if(P(z)){ans=-1*x; break;}
    x++;
    y+=x;
    z-=x;
    }
    cout<<ans<<endl;
    return 0;
    }
    

    bacchusbeale

    Posted 2014-08-27T13:28:53.350

    Reputation: 1 235

    It will be shorter to put everything on one line. – cat – 2016-06-24T13:01:42.757

    1

    Mathematica 75

    Probably can be golfed more..

    p = (j=0; b=#; While[a=IntegerDigits[b]; b += ++j(-1)^j; a!=Reverse[a]]; #-b+(-1)^j) &
    

    Spaces not counted and not needed.

    freddieknets

    Posted 2014-08-27T13:28:53.350

    Reputation: 199

    1

    CoffeeScript: 73

    (x)->(x+="")[0...(y=x.length/2)]+x[0...-y].split("").reverse().join("")-x
    

    Explanation: This takes advantage of the fact that if we have a number of odd length (say 1234567), x.slice(0, y) won't include the middle digit but x.slice(0, -y) will. JavaScript's slice probably shouldn't work this way, but it does.

    I was expecting CoffeeScript/JavaScript to have a better way to reverse a string, but the split/reverse/join method seems to be all there is.

    Justin Morgan

    Posted 2014-08-27T13:28:53.350

    Reputation: 556

    0

    QBIC, 38 bytes, nc

    :{[-1,1,2|A=!a+b*c$~A=_fA||_xb*c]c=c+1
    

    Explanation:

    The code reads an input, and then applies a modifier. It then tests to see if the number + modifier is a palindrome. Then, it flips the sigh on the modifier, re-applies that and tests again.

    :{        Read the input value, start a DO-loop
    [-1,1,2|  FOR (b = -1; b <= 1; b+=2 )
    A=!a+b*c$ Get a string from the input number, 
                plus modifier c (which is 0 at the start of QBIC)
                times -1 or 1, depending on b's iteration.
    ~A=_fA|   if that string is equal to it's own reversed version
    |_xb*c]   then Quit, printing the modifier * sign
    c=c+1     Increment the modifoer and DO-LOOP again.
              The DO-loop is implicitly closed by QBIC at EOF
    

    steenbergh

    Posted 2014-08-27T13:28:53.350

    Reputation: 7 772

    0

    Axiom, 720 594 412 bytes

    R(x)==>return x;p(r,a)==(n:=#(a::String);if r<0 then(a=0=>R a;n=1 or a=10^(n-1)=>R(a-1);a=10^(n-1)+1=>R(a-2));if r>0 then(n=1 and a<9=>R(a+1);a=10^n-1=>R(a+2));r=0 and n=1=>1;v:=a quo 10^(n quo 2);repeat(c:=v;w:=(n rem 2>0=>v quo 10;v);repeat(c:=10*c+w rem 10;w:=w quo 10;w=0=>break);r<0=>(c<a=>R c;v:=v-1);r>0=>(c>a=>R c;v:=v+1);R(c=a=>1;0));c)
    D(a:NNI):INT==(p(0,a)=1=>0;w:=p(-1,a);s:=p(1,a);a-w<s-a=>w-a;s-a)
    

    The byte count it is again this, but the algo it would be O(log(n)) because it would dipend only from the digit lenght of its input (and log10(n) would be near the lenght of the decimal digits of n). ungolfed and results

    -- Ritorna il precedente numero palidrome rispetto ad 'a' NNI, se r<0
    --                               ha la particolarita' palpn(-1,0) = 0
    -- Ritorna il successivo numero palidrome rispetto ad 'a' NNI, se r>0
    -- Se r=0 ritorna 1 se 'a' e' palindrome, 0 se 'a' non e' palindrome
    R(x)==>return x
    palpn(r,a)==
        n:=#(a::String) -- n la lunghezza in cifre di base 10 di a
        if r<0 then(a=0        =>R a;n=1 or a=10^(n-1)=>R(a-1);a=10^(n-1)+1=>R(a-2))
        if r>0 then(n=1 and a<9=>R(a+1);    a=10^n-1  =>R(a+2))
        r=0  and n=1=>1
        v:=a quo 10^(n quo 2)
        repeat -- because here not there is a goto instruction i have to use repeat
            c:=v;w:=(n rem 2>0=>v quo 10;v)
            repeat
              c:=10*c+w rem 10
              w:=w quo 10
              w=0=>break
            r<0=>(c<a=>R c;v:=v-1)
            r>0=>(c>a=>R c;v:=v+1)
            R(c=a=>1;0) -- for r==0
        c
    
    -- Ritorna la distanza minima tra l'input 'a' e una palindrome:
    --        0 se 'a' e' una palindrome
    --        r numero con segno negativo se tale palindrome precede 'a'
    --        r numero con segno positivo se tale palindrome e' successiva ad 'a'
    palDistance(a:NNI):INT==
        palpn(0,a)=1=>0
        p:=palpn(-1,a);s:=palpn(1,a)
        a-p<s-a=>p-a
        s-a
    
    --------------------------------------
    
    (3) -> [[i,D(i)] for i in [3,10,234,1299931,126]]
       (3)  [[3,0],[10,1],[234,- 2],[1299931,- 10],[126,5]]
                                                      Type: List List Integer
    (4) -> D 7978986575546463645758676970789089064235234524548028408198401348930489104890184018410
       (4)  - 199223418598327604580355025458434427119613
                                                                Type: Integer
    (5) ->  p(0,7978986575546463645758676970789089064235234524548028408198401348930489104890184018410+%)
       (5)  1
                                                        Type: PositiveInteger
    (6) -> 7978986575546463645758676970789089064235234524548028408198401348930489104890184018410+%%(-2)
       (6)
           7978986575546463645758676970789089064235234325324609809870796768575463646455756898797
                                                        Type: PositiveInteger
    

    RosLuP

    Posted 2014-08-27T13:28:53.350

    Reputation: 3 036

    The ones had spoken again (or for the complete elimination) the use of goto for computer languages, for my humble hobby programmer prospective: Are incompetent in informatics !!!! – RosLuP – 2017-11-21T09:21:54.760

    0

    Bash, 73 bytes

    i=$1;x=$i;while((x-10#$(rev<<<$x)));do ((r=(1>r)-r,x=r+i));done;echo $x
    

    Input goes to the 1st command line argument:

    foo.sh 123456789
    

    iBug

    Posted 2014-08-27T13:28:53.350

    Reputation: 2 477

    0

    Husk, 16 12 9 bytes

    ḟoS=↔+⁰İZ
    

    Thanks @H.PWiz for -4 bytes!

    Try it online!

    Explanation

    ḟ(S=↔+⁰)İZ  -- input ⁰ a number, for example: 126
            İZ  -- built-in integers: [0,1,-1,2,-2...]
    ḟ(     )    -- first element that satisfies the following (eg. 5):
         +⁰     --   add element to input: 131
      S=        --   is it equal to itself..
        ↔       --   ..reversed: 131 == 131
    

    ბიმო

    Posted 2014-08-27T13:28:53.350

    Reputation: 15 345

    0

    APL NARS 47 chars

    r←s a;b
    r←0
    A:b←⍕a+r⋄→0×⍳b≡⌽b⋄r←-r⋄→A×⍳r<0⋄r+←1⋄→A
    

    this above search but algo can not be fast and right as the g below...

    This

    A:b←⍕a+r⋄→0×⍳b≡⌽b⋄r←-r⋄→A×⍳r<0⋄r+←1⋄→A
    

    is a simple loop exit only when it find b≡⌽b so b is a string palindrome

      s¨3,10,234,1299931,126
    0 1 ¯2 ¯10 5 
    
    ∇r←g w;n;a;y;t;o;h;v
             r←0J1
       →0×⍳0≠⍴⍴w⋄→0×⍳''≡0↑w ⍝ if arg is not scalar int>=0→0J1
       →0×⍳(w<0)∨w≠⌊w
       h←{z←⍕⍺⋄q←⍕⍵⋄⍎(z,⌽q)}⍝ h return as digit ⍺⌽⍵
       n←⍴⍕w⋄r← 0
       →0×⍳n≤1              ⍝ arg one digit return r←0
       a←10*⌊n÷2
    B: v←a⋄→C×⍳∼2∣n⋄v←a×10
    C: t←⌊w÷v ⋄y←⌊w÷a
       o←y h t⋄r←(y+1)h t+1
       →D×⍳∼(∣r-w)<∣o-w⋄r←r-w⋄→0
    D: r←o-w
    ∇
    
      g¨3,10,234,1299931,126
    0 1 ¯2 ¯10 ¯5 
    

    RosLuP

    Posted 2014-08-27T13:28:53.350

    Reputation: 3 036

    0

    Python 2, 55 54 bytes

    l=lambda n,d=0:`n+d`!=`n+d`[::-1]and l(n,~d+(d<0))or d
    

    Try it online!

    ArBo

    Posted 2014-08-27T13:28:53.350

    Reputation: 1 416

    0

    Japt, 8 bytes

    nȥsw}cU
    

    Try it

    nȥsw}cU     :Implicit input of integer U
          cU     :Get the first number in the sequence [U,U-1,U+1,U-2,U+2,...,U-n,U+n]
     È           :That returns true when passed the the following function
      ¥          :  Test for equality with
       s         :  Convert to string
        w        :  Reverse
         }       :End function
    n            :Subtract U from the result
    

    Shaggy

    Posted 2014-08-27T13:28:53.350

    Reputation: 24 623

    0

    Python, 109

    def q(x,z):
     r=lambda s:int(str(s)[::-1])
     if x+z==r(x+z):return z
     if x-z==r(x-z):return -z
     return q(x,z+1)
    

    RageCage

    Posted 2014-08-27T13:28:53.350

    Reputation: 245

    this throws an error when running (maximum recursion depth exceeded) – Moop – 2014-08-27T17:47:06.403

    That's not an error in my code. It will exceed maximum recursion depth on a massive number, but it works on decently sized numbers. As there was no maximum test case in the specs, this should still be considered a valid solution. – RageCage – 2014-08-27T18:10:01.887

    1The number 123456789 causes it to fail, well below the 10^15 limit posted in the question. – Moop – 2014-08-27T18:13:16.160

    1You could easily turn the recursion into a loop and avoid this issue altogether – Moop – 2014-08-27T18:15:18.227

    A recursive solution was the shortest solution I came up with, and it's different than all the other algorithms. I'm going to leave it, it's not like it has a chance to win the challenge anyway. – RageCage – 2014-08-27T18:17:40.997

    1Running this in the Stackless Python implementation should avoid the recursion depth issue. – xnor – 2014-08-27T19:26:41.453