13
\$\begingroup\$

Write a function that takes a number as an argument and makes it a palindrome by appending minimum number of digits. The number will be at max of 100 digits.

Sample Inputs
12
122
232
2323
1012121
Sample Outputs
121
1221
232
23232
101212101
\$\endgroup\$
3
  • \$\begingroup\$ golf.shinh.org/p.rb?palindromize for reference lengths \$\endgroup\$
    – Nabb
    Feb 26 '11 at 0:28
  • \$\begingroup\$ Can the sample inputs and outputs include an example where the correct answer is an even number of digits, just to make sure that submitters cover that case? It would seem to me that some algorithms might fail if the halfway point is between digits instead of on a digit. \$\endgroup\$ May 24 '17 at 15:56
  • 1
    \$\begingroup\$ @Computronium Done. \$\endgroup\$
    – fR0DDY
    May 25 '17 at 3:01

15 Answers 15

4
\$\begingroup\$

J, 50, 32 26 characters!

f=:{.@(,"1(-:|.)\.#|.@}:\)

eg

f '12'
121 
f '232'
232   
f '2323'
23232   
f '1012121'
101212101     

How it works (by example)

y =: '1012121'

[\.y   NB. Sub lists of y
1012121
012121 
12121  
2121   
121    
21     
1 

|.\. y  NB> Reverses of sub lists of y
1212101
121210 
12121  
1212   
121    
12     
1  

([\. y) -:"1 (|. \. y) NB. Which of them are equal? (those are palindromes)
                       NB. ( -:"1 ) checks equality item by item
0 0 1 0 1 0 1

(-:  |.)\. y NB. Shortcut of the above
0 0 1 0 1 0 1

(0 0 1 0 1 0 1) # }:\y NB. Choose (#) the palindrome prefixes (\)
10    
1012  
101212

y, |.'10'   NB. Reverse and append the first prefix.
101212101
\$\endgroup\$
10
\$\begingroup\$

Perl, 32 chars

s/((.)(?1)\2|.?)$/$&.reverse$`/e

Needs Perl 5.10 or later for regex features, but no special command-line switch.

Sample use:

$ perl -pe 's/((.)(?1)\2|.?)$/$&.reverse$`/e' << EOT
> 12
> 232
> 2323
> 1012121
> EOT
121
232
23232
101212101

Uses Perl 5.10's recursive regex extensions to match the longest trailing palindrome as such:

m/
    (      # paren 1 - a palindrome is either:
      (.)  # paren 2 - a character
      (?1) # a palindrome as defined in paren 1
      \2   # the same character as in paren 2
    |        # or:
      .?   # a 0- or 1-character string
    )
    $      # at end of string
/x

It then replaces it with itself ($&) and appends whatever the string started with ($`), reversed.

\$\endgroup\$
0
5
\$\begingroup\$

Brachylog 2, 8 bytes, language postdates challenge

ẹ;AcB↔Bc

Try it online! The question asks for a function, so I provided one; the TIO link takes an argument that runs a function like a full program.

Explanation

ẹ;AcB↔Bc
ẹ          Split {the input} into digits
 ;Ac       Append {the shortest possible} list
    B↔B    to produce a palindrome
       c   then concatenate the resulting list of digits back into a number
\$\endgroup\$
3
\$\begingroup\$

Python, 88 chars

def f(x):
 x,y=list(str(x)),[]
 while x!=x[::-1]:y+=x.pop(0)
 return''.join(y+x+y[::-1])
\$\endgroup\$
1
  • \$\begingroup\$ nice with the pop. pity you can't pop from str \$\endgroup\$
    – gnibbler
    Feb 23 '11 at 20:09
2
\$\begingroup\$

Python (101 96)

edit: Shortened based on @gnibbler's solution

def p(n):s=str(n);r=s[::-1];l=len(s);return[int(s+r[l-i:])for i in range(l)if s[i:]==r[:l-i]][0] 

Original:

def p(n):
 s=str(n);r=s[::-1];l=len(s)
 for i in range(l):
  if s[i:]==r[:l-i]:return int(s+r[l-i:])
\$\endgroup\$
6
  • \$\begingroup\$ You can replace s=str(n) with s=n. \$\endgroup\$
    – fR0DDY
    Feb 23 '11 at 10:50
  • \$\begingroup\$ @fR0DDY, that wont work if n is large enough to need a long \$\endgroup\$
    – gnibbler
    Feb 23 '11 at 11:32
  • \$\begingroup\$ @fR0DDY, Python doesn't care so much about ints vs longs anymore. int(2346765434567875432456) returns 2346765434567875432456 on v2.6.5. I don't see how s=n helps; I need s to be a string so I can subscript to get digit ranges. What's the reasoning there? \$\endgroup\$ Feb 23 '11 at 11:55
  • \$\begingroup\$ @Hoa, I think fR0DDY had backticks there but they don't show up in the comments \$\endgroup\$
    – gnibbler
    Feb 23 '11 at 12:18
  • \$\begingroup\$ @Hoa It was s=[tick]n[tick]. \$\endgroup\$
    – fR0DDY
    Feb 23 '11 at 13:53
1
\$\begingroup\$

Python - 98 chars

Based on Hoa's answer :)

def p(n):s=str(n);r=s[::-1];l=len(s);return next(int(s+r[l-i:])for i in range(l)if s[i:]==r[:l-i])
\$\endgroup\$
2
  • \$\begingroup\$ Not sure I'm using this right, but: "NameError: global name 'next' is not defined" \$\endgroup\$
    – J B
    Feb 23 '11 at 12:21
  • \$\begingroup\$ @J B, Ah, you need python2.6 for that :) otherwise it can be written return(...).next() usually that would cost an extra char, but I get to drop the space after return. Hoa has improved on it again anyhow by using a LC instead of a GE \$\endgroup\$
    – gnibbler
    Feb 23 '11 at 20:07
1
\$\begingroup\$

Golfscript - 32 chars

{`:s-1%:r,,{s<r+..-1%=*}%{}?~}:f
\$\endgroup\$
1
\$\begingroup\$

Haskell, 85

Using the same algorithm as most everyone else:

import List
r=reverse
f s=s++(r.snd.head.filter g.zip(tails s)$inits s)
g(s,_)=s==r s

Examples from problem description:

*Main> map (f.show) [12,232,2323,1012121]
["121","232","23232","101212101"]
\$\endgroup\$
1
\$\begingroup\$

Ruby 1.9, 72 chars

f=->x{x=x.to_s.split'';99.times{|i|x.insert~i,x[i]if x!=x.reverse};x*''}
\$\endgroup\$
2
  • \$\begingroup\$ x*'' instead of x.join saves 2 chars. \$\endgroup\$
    – steenslag
    Feb 23 '11 at 18:10
  • 1
    \$\begingroup\$ nice one @steenslag, thanks for teaching, I am ruby newbie :-) \$\endgroup\$
    – YOU
    Feb 23 '11 at 18:12
1
\$\begingroup\$

Ruby, 70 bytes

f=->x{x=x.to_s.chars;99.times{|i|x.insert~i,x[i]if x!=x.reverse};x*''}

Try it online!

Based on YOU'S answer, with chars instead of .split'' to gain 2 chars. And i'm sure there's way to squeeze just a bit more ><

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 145 126 chars

 p=a=>{S=x=>x.split``.reverse();for(s=String(a),i=0;i<s.length;i++)if(x=s+S(s.substring(0,i)).join``,x==S(x).join``)return x}

Commented:

function palindrome(n){
  s = String(n);
  for(i=0;i<s.length;i++)
  {
    x=s+s.substring(0,i).split("").reverse().join("") //take first n characters, reverse and append to the end
    if(x==x.split("").reverse().join("")) //is the number a palindrome?
      return x;
  }
}
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 27 7 bytes

-18 bytes thanks to @Razetime.

ηí«.ΔÂQ

Try it online!

ηí«.ΔÂQ  # full program
   .Δ    # find first element in...
  «      # joined...
 í       # reversed...
η        # prefixes of...
         # implicit input...
   .Δ    # where...
      Q  # it's equal to...
     Â   # itself reversed
         # implicit output
\$\endgroup\$
2
  • \$\begingroup\$ Isn't this much simpler and shorter? \$\endgroup\$
    – Razetime
    Dec 14 '20 at 12:49
  • \$\begingroup\$ Yes, thank you! I've made a couple optimizations by replacing DR with  and removing the implicit }. \$\endgroup\$
    – Makonede
    Dec 15 '20 at 17:05
0
\$\begingroup\$

Java, 174 bytes

x->{Function<String,String>r=t->new StringBuilder(t).reverse().toString();String y=r.apply(x),z=x;int m=x.length();while(!z.equals(r.apply(z)))z=x+y.substring(--m);return z;}

Ungolfed:

x -> {
        Function<String, String> r = t -> new StringBuilder(t).reverse().toString();
        String y = r.apply(x), z=x;
        int m = x.length();
        while (!z.equals(r.apply(z))) z = x+y.substring(--m);
        return z;
    }

I have a feeling it could be a lot tighter but it's not immediately obvious to me how. The Function eats up a lot of space but I needed it in two places.

This works for any string, not just numbers, and it can be any length.

\$\endgroup\$
0
\$\begingroup\$

PHP, 64 Bytes

for(;strrev($p=$argn.strrev(substr($argn,0,$i++)))!=$p;);echo$p;

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 11 bytes

D;ⱮUƤ$ŒḂƇḢḌ

Try it online!

How it works

D;ⱮUƤ$ŒḂƇḢḌ - Main link. Takes n on the left
D           - Digits of n
     $      - To the digits of n:
    Ƥ       -   Yield the prefixes
   U        -   Reverse
 ;Ɱ         -   Concatenate with the digits
      ŒḂƇ   - Keep the palindromes
         Ḣ  - Take the first (i.e. the shortest)
          Ḍ - Convert from digits
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.