How to resolve the algorithm Lychrel numbers step by step in the Python programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Lychrel numbers step by step in the Python programming language

Table of Contents

Problem Statement

The above recurrence relation when applied to most starting numbers n = 1, 2, ... terminates in a palindrome quite quickly.

If n0 = 12 we get And if n0 = 55 we get Notice that the check for a palindrome happens   after   an addition.

Some starting numbers seem to go on forever; the recurrence relation for 196 has been calculated for millions of repetitions forming numbers with millions of digits, without forming a palindrome. These numbers that do not end in a palindrome are called Lychrel numbers. For the purposes of this task a Lychrel number is any starting number that does not form a palindrome within 500 (or more) iterations.

Any integer produced in the sequence of a Lychrel number is also a Lychrel number. In general, any sequence from one Lychrel number might converge to join the sequence from a prior Lychrel number candidate; for example the sequences for the numbers 196 and then 689 begin: So we see that the sequence starting with 689 converges to, and continues with the same numbers as that for 196. Because of this we can further split the Lychrel numbers into true Seed Lychrel number candidates, and Related numbers that produce no palindromes but have integers in their sequence seen as part of the sequence generated from a lower Lychrel number.

Show all output here.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Lychrel numbers step by step in the Python programming language

This code is a Python implementation for finding Lychrel numbers. Lychrel numbers are numbers that do not converge to a palindrome under the iteration x -> x + reverse(x). The code takes two input parameters: maxn, which is the upper limit of the search range, and max_reversions, which is the maximum number of iterations allowed for each number.

The code uses two functions, add_reverse() and reverse_int(), to perform the core operations of the Lychrel number search. The add_reverse() function takes a number num as input and returns a set of all the numbers that are reached by repeatedly adding the number to its reverse, up to a maximum of max_iter iterations. The reverse_int() function takes a number num as input and returns its reverse.

After defining these functions, the code uses them to find Lychrel numbers and related numbers within the specified range. It first generates a list of sets of numbers for each number in the range [1, maxn]. Each set contains all the numbers that are reached by repeatedly adding the number to its reverse, up to a maximum of max_reversions iterations.

The code then uses the split_roots_from_relateds() function to split the list of sets into two lists: one containing the roots of the Lychrel numbers (i.e., the numbers that do not converge to a palindrome) and one containing the related numbers (i.e., the numbers that do converge to a palindrome).

Finally, the code prints out the number of Lychrel numbers, the list of Lychrel numbers, the number of related numbers, and the list of Lychrel palindromes (i.e., the Lychrel numbers that are also palindromes).

Here is a breakdown of the key functions and data structures used in the code:

  • add_reverse(): This function takes a number num as input and returns a set of all the numbers that are reached by repeatedly adding the number to its reverse, up to a maximum of max_iter iterations.
  • reverse_int(): This function takes a number num as input and returns its reverse.
  • split_roots_from_relateds(): This function takes a list of sets of numbers as input and splits it into two lists: one containing the roots of the Lychrel numbers and one containing the related numbers.

The main data structure used in the code is a list of sets of numbers. Each set contains all the numbers that are reached by repeatedly adding a particular number to its reverse, up to a maximum of max_iter iterations.

The code uses these functions and data structures to efficiently find Lychrel numbers and related numbers within a specified range.

Source code in the python programming language

from __future__ import print_function

def add_reverse(num, max_iter=1000):
    i, nums = 0, {num}
    while True:
        i, num = i+1, num + reverse_int(num)
        nums.add(num)
        if reverse_int(num) == num or i >= max_iter:
            break
    return nums
    
#@functools.lru_cache(maxsize=2**20)
def reverse_int(num):
    return int(str(num)[::-1])

def split_roots_from_relateds(roots_and_relateds):
    roots = roots_and_relateds[::]
    i = 1
    while i < len(roots):
        this = roots[i]
        if any(this.intersection(prev) for prev in roots[:i]):
            del roots[i]
        else:
            i += 1
    root = [min(each_set) for each_set in roots]
    related = [min(each_set) for each_set in roots_and_relateds]
    related = [n for n in related if n not in root]
    return root, related

def find_lychrel(maxn, max_reversions):
    'Lychrel number generator'
    series = [add_reverse(n, max_reversions*2) for n in range(1, maxn + 1)]
    roots_and_relateds = [s for s in series if len(s) > max_reversions]
    return split_roots_from_relateds(roots_and_relateds)


if __name__ == '__main__':
    maxn, reversion_limit = 10000, 500
    print("Calculations using n = 1..%i and limiting each search to 2*%i reverse-digits-and-adds"
          % (maxn, reversion_limit))
    lychrel, l_related = find_lychrel(maxn, reversion_limit)
    print('  Number of Lychrel numbers:', len(lychrel))
    print('    Lychrel numbers:', ', '.join(str(n) for n in lychrel))
    print('  Number of Lychrel related:', len(l_related))
    #print('    Lychrel related:', ', '.join(str(n) for n in l_related))
    pals = [x for x in lychrel + l_related  if x == reverse_int(x)]
    print('  Number of Lychrel palindromes:', len(pals))
    print('    Lychrel palindromes:', ', '.join(str(n) for n in pals))


from __future__ import print_function

def rev(n): return int(str(n)[::-1])

def lychel(n, cache = {}):
    if n in cache: return cache[n]

    n0, r = n, rev(n)
    res, seen = (True, n), []
    for i in range(1000):
        n += r
        r = rev(n)
        if n == r:
            res = (False, 0)
            break
        if n in cache:
            res = cache[n]
            break
        seen.append(n)

    for x in seen: cache[x] = res
    return res

seeds, related, palin = [], [], []

for i in range(1, 1000000):
    tf, s = lychel(i)
    if not tf: continue
    (seeds if i == s else related).append(i)
    if i == rev(i): palin.append(i)

print("%d Lychel seeds:"%len(seeds), seeds)
print("%d Lychel related" % len(related))
print("%d Lychel palindromes:" % len(palin), palin)


  

You may also check:How to resolve the algorithm I before E except after C step by step in the Arturo programming language
You may also check:How to resolve the algorithm Hofstadter Figure-Figure sequences step by step in the Rust programming language
You may also check:How to resolve the algorithm Sorting algorithms/Heapsort step by step in the Dart programming language
You may also check:How to resolve the algorithm Permutation test step by step in the C++ programming language
You may also check:How to resolve the algorithm Hostname step by step in the Standard ML programming language