40
\$\begingroup\$

Write a short program for 196-algorithm. The algorithm starts from an integer, then adds its reverse to it until a palindrome is reached.

e.g.

input = 5280
5280 + 0825 = 6105
6105 + 5016 = 11121
11121 + 12111 = 23232
output = 23232

Input

an integer, which is not a lyrchrel number (that is, it does eventually yield a palindrome under this algorithm, rather than continuing infinitely)

Output

the palindrome reached.

\$\endgroup\$
12
  • 1
    \$\begingroup\$ @Nakilon please give a reason for your edit. \$\endgroup\$
    – Eelvex
    Jan 29, 2011 at 8:31
  • 7
    \$\begingroup\$ Because your question is probably the only one involving the 196 algorithm. Making single-use tags is not useful. \$\endgroup\$ Jan 29, 2011 at 8:48
  • 1
    \$\begingroup\$ @Chris: It's a private beta with 34 questions so far; single-use tags is a normal thing at this point. Anyway, let's leave it as it is for now, retagging later is always an option :) \$\endgroup\$
    – Eelvex
    Jan 29, 2011 at 9:07
  • 2
    \$\begingroup\$ What I meant was, your question is likely to be the only one ever to involve this topic, even in 2 years' time. :-) \$\endgroup\$ Jan 29, 2011 at 9:12
  • 2
    \$\begingroup\$ @Chris: Well, 196-algorithm is a pretty popular one, going by many different names. Just to be sure, though, I'll post another question about it before the 2-year-time lapses ;) \$\endgroup\$
    – Eelvex
    Jan 29, 2011 at 9:49

55 Answers 55

1
2
2
\$\begingroup\$

GNU dc, 46 bytes

Requires GNU dc, min version 1.4 (for R command).

[O~3RO*+rd0<R]sR[+lfx]sg[ddO~rd0<R+d3R!=g]dsfx

Input and output are top-of-stack, as usual. It takes a surprising amount of code to reverse digits in dc (unless I'm missing something, which is far from impossible). It does have the numeric range to behave nicely with inputs such as these (which will overflow 32-bit unsigned arithmetic, for example):

  • 89 ⇒ 8,813,200,023,188
  • 8997 ⇒ 16,668,488,486,661
  • 10677 ⇒ 4,668,731,596,684,224,866,951,378,664

Explanation

# Reverse digits, starting after first digit extracted
[O~3RO*+r d0<R]sR

# Recursion helper - add and recurse
[+ lfx]sg

# Main recursive function
[dd O~r d0<R+ d3R !=g]dsfx
\$\endgroup\$
5
  • \$\begingroup\$ Try it online! (Javascript) \$\endgroup\$ Aug 2, 2018 at 14:11
  • \$\begingroup\$ Might want to specify that this works only on GNU dc 1.4 and later, since it uses the new R command. Good solution, though! \$\endgroup\$ Aug 3, 2018 at 18:29
  • \$\begingroup\$ I'm working on a totally different approach but not sure it will wind up smaller. \$\endgroup\$ Aug 3, 2018 at 18:31
  • \$\begingroup\$ Thanks Sophia - I hadn't realised that R was new. Looking forward to seeing your method! \$\endgroup\$ Aug 6, 2018 at 7:15
  • \$\begingroup\$ Ah, nope...I tried a different approach to arranging the outside loop but it ended up about five bytes larger and no prettier. You win. =) \$\endgroup\$ Aug 6, 2018 at 16:27
2
\$\begingroup\$

R, 193 109 105 bytes

-84 bytes thanks to Giuseppe! -4 byes thanks to JayCe!

function(x){"-"=utf8ToInt
S=strtoi
"!"=rev
while({z=paste(S(x)+S(intToUtf8(!-x),10));any(-z!=!-z)})x=z
z}

Try it online!

\$\endgroup\$
8
  • 1
    \$\begingroup\$ You can (and should) choose a different way of doing this than string manipulation, but here are some golfing tips for the method you've chosen: strsplit(x,"") is shorter than strsplit(x,NULL), and el(L) is shorter than L[[1]]. as.double is shorter than as.numeric and strtoi is shorter than both; instead of setting t just use it directly in your if statement. also this is a recursive function if I'm not mistaken, so you need to put f= as part of your submission. \$\endgroup\$
    – Giuseppe
    Aug 2, 2018 at 15:51
  • \$\begingroup\$ @Giuseppe Got it. Thanks for the tips. I'll keep working on this. It's easier for me to just get something that works then go back and optimize. \$\endgroup\$
    – Robert S.
    Aug 2, 2018 at 16:01
  • 1
    \$\begingroup\$ Hehehe, no worries. If you're hell-bent on using strings (or forced to by the problem), consider utf8ToInt to convert to digits and intToUtf8 to convert back. That'll be a big byte saving! \$\endgroup\$
    – Giuseppe
    Aug 2, 2018 at 16:07
  • 1
    \$\begingroup\$ Here is a 109 bytes golf using utf8ToInt and a while loop \$\endgroup\$
    – Giuseppe
    Aug 2, 2018 at 17:58
  • 1
    \$\begingroup\$ Save 4 more bytes by using - in place of U. I also replaced rev with ! but it does not save any byte... \$\endgroup\$
    – JayCe
    Aug 6, 2018 at 17:02
2
\$\begingroup\$

Thunno 2, 7 bytes

(ḲQ;ḲN+

Attempt This Online!

Explanation

(ḲQ;ḲN+  # implicit input
(  ;     # while loop
  Q      # (condition)  not equal to
 Ḳ       #              its reverse
     N+  # (body)       add
    Ḳ    #              the reverse
         # implicit output
\$\endgroup\$
1
\$\begingroup\$

Javascript ES6, 56 bytes

f=a=>(g=_=>[...""+a].reverse().join``)()==a?a:f(a+ +g())
\$\endgroup\$
1
\$\begingroup\$

Dyalog APL, 17 bytes

{⍵+⍎⌽⍕⍵}⍣{⍺≡⍎⌽⍕⍺}

{⍵+⍎⌽⍕⍵} add argument and its reverse...
... until...
{⍺≡⍎⌽⍕⍺} ... the result is a palindrome.

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

PHP, 57 Bytes

Try it online!

Code, recursive function

function f($n){echo(strrev($n)!=$n)?f(strrev($n)+$n):$n;}

Explanation

function f($n){
    echo(strrev($n)!=$n)? #check if non-palindrome
        f(strrev($n)+$n): #true, call again with $n + reverse $n
        $n;               #false (is a palindrome) echo $n

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

Java, 90 84 bytes

n->{for(long t;(t=new Long(new StringBuffer(n+"").reverse()+""))!=n;)n+=t;return n;}

-6 bytes thanks to @O.O.Balance.

Try it online.

Explanation:

n->{           // Method with long as both parameter and return-type
  for(long t;  //  Temp-long, starting uninitialized
      (t=new Long(new StringBuffer(n+"").reverse()+""))
               //  Before every iteration, reverse the temp-long
      !=n;)    //  And loop as long as it's not equal to `n` yet
    n+=t;      //   Add this temp-long to the input
  return n;}   //  Return the modified input as result
\$\endgroup\$
1
1
\$\begingroup\$

Perl 6, 36 bytes

{($_,{$_+.flip}...{$_==.flip})[*-1]}

Try it online!

An anonymous code block that returns the last element of a sequence defined by:

  • The first element is the first parameter
  • The i+1th element is the ith element plus the reverse of itself
  • And ends when the element is equal to its reverse
\$\endgroup\$
1
\$\begingroup\$

Husk, 7 bytes

¤Ω`S↔=+

Try it online!

Alternatively we could use ΩS=↔S+↔ for the same amount of bytes, but I like the one above more.

Explanation

¤Ω`S↔=+
¤        -- compose the arguments of
 Ω       -- | iterate second function until first is truthy
         -- with
  `S     -- | flipped S: applying binary function to itself and
    ↔    -- | | itself reversed
         -- first function: check if palindrome (\x-> x == reverse x)
         -- second function: "196ify" (\x-> x + reverse x)
\$\endgroup\$
1
\$\begingroup\$

Ruby, 55 bytes

l=->x{x.reverse==x ? x:l[(x.to_i+x.reverse.to_i).to_s]}

Different approach than the other Ruby one, ended up golfing it down to one byte fewer

Explanation: makes a lambda l that recursively calls itself, each time adding the number's reverse, until the string is a palindrome

Slightly less golfed version:

func = ->x do
  (x.reverse == x) ? x : func[(x.to_i + x.reverse.to_i).to_s]
end
\$\endgroup\$
1
\$\begingroup\$

Excel VBA, 49 bytes

An immediate window function which takes input from range [A1] and outputs to the VBE immediate window.

n=[A1]:Do:n=n+r:r=StrReverse(n):Loop While n-r:?n
\$\endgroup\$
1
\$\begingroup\$

Lua 5.3.3, 57 bytes

Takes i as input, prints output:

r=0while i~=r do i=i+r|0r=0+(i..""):reverse()end print(i)

More readable version:

r=0
while i~=r do
  i=i+r|0
  r=0+(i..""):reverse()
end
print(i)

Super simple. Just repeatedly adds i to its reverse until i is equal to its reverse. Then it just prints the new value of i.

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

Actually, 16 bytes

;WX;$R≈+;$;R=YWX

Try it online!

Explanation:

;WX;$R≈+;$;R=YWX
;                 push a copy of n
 W            W   while top of stack is truthy:
  X                 pop and discard
   ;$R≈+            copy n, cast to string, reverse, cast to int, add
        ;$;R=Y      not palindrome (cast to string, copy, reverse, check inequality)
               X  pop and discard
\$\endgroup\$
1
\$\begingroup\$

J, 27 bytes

(+&.".|.)^:(-.@-:|.)^:_&.":

Try it online!

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

Python 2, 53 bytes

f=lambda x,y=0:x if x==y else f(x+y,int(`x+y`[::-1]))

Try it online!

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

Ruby, 47 bytes

->a{v=a.to_s.reverse;v==a.to_s ? a:f[a+v.to_i]}

Try it online!

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

Japt, 11 10 bytes

@¶ìw}a@±ìw

Try it

@¶ìw}a@±ìw     :Implicit input of integer U
@              :Left function
 ¶             :  Test U for equality with
  ì            :  Convert to digit array
   w           :    Reverse and convert back to integer
    }          :End function
     a         :Get the first result of the right function that returns true when run through the left function
      @        :Right function
       ±       :  Increment U by
        ìw     :  As above
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 6 bytes

{Ḃ≠|m:

Try it Online!

Wooo cursed behaviour for numbers ftw.

Explained

{Ḃ≠|m:
{Ḃ≠|      # while t.o.s[::-1] != tos:
    m     #     mirror the tos (that is, add the reverse of the number to the number)
     :    #     and duplicate the tos so that the while loop condition has a value to work on.
\$\endgroup\$
1
1
\$\begingroup\$

Python 2, 49 bytes

\$n\$ added to its reverse is \$2n\$ iff \$n\$ is a palindrome.

f=lambda n,r=0:n-r*2and f(n+int(`n`[::-1]),n)or r

Try it online!

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

MATL, 18 bytes

`Vt2&P=?5M.}1MvUsT

Try it on MATL Online

         % (implicit input)
`        % do-while loop
  Vt     % convert the number into a string, duplicate it
  2&P    % flip the copy left-to-right
  =      % are they equal? 
    ?5M. % if yes, push the number back on the stack and exit
         % (implicit output display)
    }1M  % else, push the number and its reverse (as strings) again on to the stack
    vUs  % convert them to numbers and add them
    T    % "True" value to continue loop, this time with the sum as the input number
         % (implicit loop end)
\$\endgroup\$
1
\$\begingroup\$

Pyt, 10 bytes

`ΠĐ₫+Đ₽¬ł+

Try it online!

`       ł          do... while top of stack is not 0
 Π                 product of everything on the stack (gets input on first pass;
                       otherwise removes the pesky 1 that resulted from the loop checking)
  Đ                Đuplicate 
   ₫               reverse the ₫igits
    +              add
     Đ             Đuplicate
      ₽¬           is the result not a ₽alindrome?
         +         add (removes the pesky 0 that was used to break out of the loop)
\$\endgroup\$
0
\$\begingroup\$

Wren, 102 bytes

A super long program.

Fn.new{|x|
while(x!=x[-1..0])x=(Num.fromString(x)+Num.fromString(x[-1..0])).toString
System.write(x)
}

Try it online!

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

Vyxal, 7 bytes

{:Ḃ≠|Ḃ+

Try it Online!

{       # While...
 :Ḃ≠    # It's not a palindrome
    |   # Do...
     Ḃ+ # Concatenate to its reverse
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 46 bytes

f=n=>[r=``,...n+r].map(d=>r=d+r)|n-r?f(+r+n):n

Try it online!

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

Rattle, 12 bytes

|[st[~q]+~]0

Try it Online!

Explanation

|              take input
 [ ....... ]0  infinite loop
   s           save top of stack to storage
    t          reverse this value
     [~ ]      execute if the reversed value is equal to the saved value
       q       quit the program, the result is printed implicitly
         +~    add the stored value to the current value

Rattle, 21 bytes (a different approach)

|[st+~s1/~[2g1/q]g1]0

Try it Online!

Explanation

|                    take input
 [ ... ]0            infinite loop
 
  s                  save top of stack to storage in slot 0
   t                 reverse top of stack
    +~               add value in slot 0 to top of stack
      s1             save result in slot 1
        /~           divide this by the value in slot 0 (the previous number)
          
  [2 ... ]           if the result is exactly 2, execute code inside if statement
    g1               get value in slot 1
      /              divide (with no argument, divides by 2)
       q             quit program, top of stack is output implicitly
          g1         get value in slot 1
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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