Author Topic: Palindrome Lychrel Numbers  (Read 7605 times)

B+

  • Guest
Palindrome Lychrel Numbers
« on: January 14, 2016, 01:53:47 am »
In Just Basic, the most recent discussion has been about Lychrel numbers. Considering the way Lychrel numbers are determined, I thought it amusing to find Palindromes that turn out to be Lychrel like in 50 rounds of sums of a number and a reverse. (Lychrel numbers never produce a palindrome number but here we are satisfied it is Lychrel like if no palindromes show up in 50 rounds.) So maybe you can see the irony of starting with palindrome numbers.

Code: [Select]
'palindrome Lychrel numbers for JB 2016-01-13 B+=MGA
print "Palindrome Lychrel(-like in 50 rounds) numbers:"
global pcount
while pcount<100
    i=i+1
    scan
    if isPalindrome(i) then
        if is50Lychrel(i) then call show i
    end if
wend
print:print "Palindrome Lychrel count is ";pcount

sub show pal
    print using("#######",pal);
    pcount=pcount+1
    if pcount mod 10 =0 then print
end sub

function reverse(num)
    snum$=str$(num)
    for I=1 to len(snum$)
        p$=mid$(snum$,I,1)+p$
    next
    reverse=val(p$)
end function

function is50Lychrel(num)
    is50Lychrel=0
    t$=str$(num+reverse(num))
    for j=1 to 50
        p$=str$(reverse(val(t$)))
        if p$=t$ then exit function else t$=str$(val(t$)+val(p$))
    next j
    is50Lychrel=1
end function

function isPalindrome(num)
    if str$(num)=str$(reverse(num)) then isPalindrome=1 else isPalindrome=0
end function

Output
Code: [Select]
Palindrome Lychrel(-like in 50 rounds) numbers:
   4994   8778   9999  11811  19591  22822  23532  23632  23932  24542
  24742  24842  24942  26362  27372  29792  29892  33933  34543  34743
  34943  39493  44744  46064  46164  46364  46564  46964  47274  47574
  48284  48584  48684  48884  49394  49794  53935  61916  62826  64046
  64346  64446  64846  66466  67976  68486  68986  73537  78587  79297
  82928  83038  83238  83638  83838  84448  87378  87578  88388  89198
  92229  94449  94549  95359  95759  97479  98089  98289  98389  98589
  98989  99999 118811 119911 193391 219912 235532 236632 239932 246642
 247742 253352 259952 263362 269962 278872 289982 293392 294492 306603
 317713 339933 347743 348843 351153 361163 362263 364463 373373 376673

Palindrome Lychrel count is 100




Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #1 on: January 14, 2016, 07:41:25 pm »
Python:

Code: [Select]
k, x = 100, 1
while k:
y, z = x, 50
y = y + int(str(y)[::-1])
while str(y) != str(y)[::-1] and z > 0:
y = y + int(str(y)[::-1])
z -= 1
if z == 0 and str(x) == str(x)[::-1]:
print(x)
k -= 1
x += 1

string[::-1] returns reversed string.

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #2 on: January 14, 2016, 07:55:22 pm »
Hi Tomaaz,

Nice! Do we end on same number?

Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #3 on: January 15, 2016, 02:15:32 pm »
Yes, 376673.

Here is a Ruby version:
Code: [Select]
k, x = 100, 1
while k > 0
y, z = x, 50
y = y + y.to_s.reverse.to_i
while y.to_s != y.to_s.reverse and z > 0
y = y + y.to_s.reverse.to_i
z -= 1
end
if z == 0 and x.to_s == x.to_s.reverse
puts x
k -= 1
end
x += 1
end

IMHO, it's more clear and easier to read than Python and BASIC. It's a shame that Ruby doesn't really exist outside Rails. :(

Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #4 on: January 15, 2016, 02:43:14 pm »
And if you change the number of sums from 50 to 500, the result is almost exactly the same. Only one number is gone and one new number added.
« Last Edit: January 15, 2016, 02:47:02 pm by Tomaaz »

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #5 on: January 15, 2016, 10:33:47 pm »
Hi Tomaaz,

HA! I started converting and modifying in SmallBASIC because it would run faster than JB but I started getting very strange results. A real head scratcher until I started printing intermediate results to debug code and realized the error of my ways. SmallBASIC has a precision of 14 decimal places before it gets real with exponents.

So Ruby, like Python can do extended integer math like JB (and probably faster) and SmallBASIC sure can't.

How long did Ruby take to the 500 rounds to see if the Palindrome number was Lychrel like?

Running my revised JB code now.

EDIT: 8 mins later got same set of numbers, dang it I forgot to change j test!

« Last Edit: January 15, 2016, 10:42:25 pm by B+ »

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #6 on: January 15, 2016, 10:56:07 pm »
Confirmed one new number. (Why aren't the code tags working???) :???

Code: [Select]
'palindrome Lychrel numbers for JB 2016-01-15 revise better copy than one posted B+=MGA
print "Palindrome Lychrel(-like in 500 rounds) numbers:"
global pcount
while pcount<100
    i=i+1
    if i=reverse(i) then
        t=i+reverse(i)
        for j=1 to 500
            scan
            p=reverse(t)
            if p=t then exit for else t=t+p
        next j
        if j>500 then call show i
    end if
wend
print:print "Palindrome Lychrel count is ";pcount

sub show pal
    print using("#######",pal);
    pcount=pcount+1
    if pcount mod 10 =0 then print
end sub

function reverse(num)
    snum$=str$(num)
    for I=1 to len(snum$)
        p$=mid$(snum$,I,1)+p$
    next
    reverse=val(p$)
end function



Output
Code: [Select]
Palindrome Lychrel(-like in 500 rounds) numbers:
   4994   8778   9999  11811  19591  22822  23532  23632  23932  24542
  24742  24842  24942  26362  27372  29792  29892  33933  34543  34743
  34943  39493  44744  46064  46164  46364  46564  46964  47274  47574
  48284  48584  48684  48884  49394  49794  53935  61916  62826  64046
  64346  64446  64846  66466  67976  68486  68986  73537  78587  79297
  82928  83038  83638  83838  84448  87378  87578  88388  89198  92229
  94449  94549  95359  95759  97479  98089  98289  98389  98589  98989
  99999 118811 119911 193391 219912 235532 236632 239932 246642 247742
 253352 259952 263362 269962 278872 289982 293392 294492 306603 317713
 339933 347743 348843 351153 361163 362263 364463 373373 376673 378873

Palindrome Lychrel count is 100

Can you figure the missing number?

Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #7 on: January 16, 2016, 12:02:26 am »
How long did Ruby take to the 500 rounds to see if the Palindrome number was Lychrel like?

The whole program (calculating and printing all 100 numbers) takes:

50 rounds

Python - 7s.
Ruby -  8s.

500 rounds

Python - 1min. 30s.
Ruby - 6min.

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #8 on: January 16, 2016, 01:08:36 am »
Yep! way better times JB takes a couple of minutes for 50 rounds and maybe 8 minutes for 500 rounds while I surf Internet.

Here is code to find the number eliminated going from 50 rounds to 500, kind of ridiculous but I needed practice. I thought it would be a snap but strings from TLOAD were loaded with junk besides the numbers and spaces.

Code: [Select]
'find missing number.bas for SmallBASIC 0.12.2 2016-01-15 [B+=MGA]

dim a1(120),a2(120)
tload "pl1.txt",pl1,1
tload "pl2.txt",pl2,1
build="":idx1=1:idx2=1
for i=1 to len(pl1)
  if instr("1234567890",mid(pl1,i,1)) then
    build=build+mid(pl1,i,1)
  else
    if len(build) then
      insert a1,idx1,build
      idx1++
      build=""
    end if
  end if
next
build=""
for i=1 to len(pl2)
  if instr("1234567890",mid(pl2,i,1)) then
    build=build+mid(pl2,i,1)
  else
    if len(build) then
      insert a2,idx2,build
      idx2++
      build=""
    end if
  end if
next
for i=1 to (idx1-1)
  if a1(i)<>a2(i) then
    print a1(i);" is the first number eliminated by increasing rounds from 50 to 500."
    exit for
  end if
next
pause

Here is code I used to see how many rounds (after 50 and before 500) that one number took to become palindrome.

Code: [Select]
'Lychrel test for JB 2016-01-15 [B+=MGA]
while 1
    print:input "Enter a number to test if Lychrel like in 500 rounds <10 quits ";test
    if test<10 then end
    t=test+reverse(test)
    for j=1 to 500
        p=reverse(t)
        if p=t then exit for else t=t+p
    next j
    if j>500 then print test;" is Lychrel-like." else print "Palindrome found for ";test;" in ";j;" rounds."
wend

function reverse(num)
    snum$=str$(num)
    for I=1 to len(snum$)
        p$=mid$(snum$,I,1)+p$
    next
    reverse=val(p$)
end function


Ha, 52 rounds to become palindrome for the one number eliminated by increasing from 50 to 500.
« Last Edit: January 16, 2016, 01:35:31 am by B+ »

Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #9 on: January 16, 2016, 09:10:45 am »
Yep! way better times JB takes a couple of minutes for 50 rounds and maybe 8 minutes for 500 rounds while I surf Internet.

I wasn't really thinking about speed when I created these scripts. So, here is a new version in Ruby:

Code: [Select]
k, x = 100, 1
while k > 0
while x != x.to_s.reverse.to_i
x += 1
end
y, z = x, 50
y = y + y.to_s.reverse.to_i
while y.to_s != y.to_s.reverse and z > 0
y = y + y.to_s.reverse.to_i
z -= 1
end
if z == 0
puts x
k -= 1
end
x += 1
end

This one takes 0.3 sec for 50 rounds, 2 sec for 500 and 5 min for 5000 rounds.

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #10 on: January 16, 2016, 05:27:17 pm »
Hi Tomaaz,

Very impressive change, looks about same to me ?? Only one or two guys I know who might beat that speed with their Basics. But I am not seeing any neatly formatted printouts... ;)

OK, so what is .to_s and .to_i, and Ruby has built in "reverse" used about the same way I named my function (great minds think alike) ?

Is Ruby recognized by browsers like JavaScript?

Tomaaz

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #11 on: January 16, 2016, 06:16:01 pm »
Very impressive change, looks about same to me ??

First example tested all numbers, but printed only palindromes. This one's testing only palindromes.

Only one or two guys I know who might beat that speed with their Basics.

I'd love to see a code in BASIC that is as fast and as compact like Ruby or Python example. ;)

OK, so what is .to_s and .to_i, and Ruby has built in "reverse" used about the same way I named my function (great minds think alike) ?

Ruby is fully object oriented language. Everything in Ruby is an object and objects are manipulated by methods (functions in other languages). To apply a method to an object you write a name of the object, a dot and the name of the method. to_s, to_i and reverse are examples of Ruby's method. to_s converts to string. to_i converts to integer. Object oriented code should be read from left to right, like a book. So, x.to_s.reverse.to_i means take x, convert it to string, reverse that string and convert the result to integer. In BASIC it would look like int(reverse(str(x))). IMHO, the Ruby way is easier to follow. Not only it reads from left to right, but you also don't need to follow parenthesis. Python is somewhere in between. It's got old school, BASIC-like int(), str() and len() etc., but majority functions are used the same way Ruby does it - with dot.

Is Ruby recognized by browsers like JavaScript?

No. Ruby is a general purpose language, but it's mostly used as a server side scripting tool (Rails is the most popular framework). However, Ruby can be used on your computer the same way Python or BASIC can. On Linux you can install it from your distro repository (sometimes, it's preinstalled, but not often). On Windows you can get it from http://rubyinstaller.org/ . Alternatively you can try Shoes which is a simple Ruby GUI toolkit.

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #12 on: January 16, 2016, 07:16:17 pm »
Hi Tomaaz,

Thanks for replies and links (good to get back some BP.org info)! That is an excellent point about parenthesis I had never considered before.

ZXDunny

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #13 on: January 17, 2016, 07:57:36 pm »
I tried this, but with the first number (4994) adding itself to it's reversed version ended up with a number so huge it turned to scientific notation and reversing one of those and then trying to find its value is not going to work :(

D.

B+

  • Guest
Re: Palindrome Lychrel Numbers
« Reply #14 on: January 17, 2016, 08:20:16 pm »
Hi D,

First off just to be clear, 4994 is Lychrel and so never (theoretically) hits palindrome status again.

2nd you just found Just Basic advantage, extended integer math. This is why I couldn't do this with SmallBASIC as mentioned earlier in this thread.

Were you testing for 50 rounds or 500 rounds?

Here is SmallBASIC code that bombs out with 4994:
Code: [Select]
'palindrome Lychrel numbers.bas for SmallBASIC 0.12.2 [B+=MGA]
'modified from JB 2016-01-13 B+=MGA and Tomaaz Ruby version
' OH OH OH this won't work in SmallBASIC!!!!!!
' The number precision is lost after 14 digits or less even

'goto test100
'test Lychrel tester
label start
?:input "Enter number to test if Lycrel (<=10 quits) ";test
if test<10 then end
if is50Lychrel(test) then ? "Lychrel" else ? "Not Lychrel"
goto start
'
label test100
i=10:s=" Palindrome Lychrel Numbers"
repeat
    i++
    if i=reverse(i) then
      if is50Lychrel(i) then
        print using "#######";i;
        pcount++
        if pcount%10=0 then print
      end if
    end if
until pcount=100
?:? space((67-len(s))/2);pcount;s
pause

func reverse(num)
  local snum,i,p
  snum=str(num)
  p=""
  for i=1 to len(snum)
    p=mid(snum,i,1)+p
  next
  reverse=val(p)
end

func is50Lychrel(num)
  local t,j,p
  ? "enter is50Lychrel with ";num
    is50Lychrel=0
    t=num+reverse(num)
    print "first test t is ";t
    for j=1 to 50
        p=reverse(t)
        print "p is ";p
        if p=t then ? "p=t so exit not Lychrel":exit func else ? "t<>p so continue":t=t+p:? "t is ";t
    next j
    ?"Exit function is Lychrel"
    is50Lychrel=1
end

14 places is maximum SmallBASIC can handle before have to get REAL= floats or scientific notation.

As you can see, I was only testing for 50 rounds.



« Last Edit: January 17, 2016, 08:30:08 pm by B+ »