Task: Lychrel numbers


C++: #include <iostream>
#include <map>
#include <vector>
#include <gmpxx.h>

using integer = mpz_class;

integer reverse(integer n) {
    integer rev = 0;
    while (n > 0) {
        rev = rev * 10 + (n % 10);
        n /= 10;
    }
    return rev;
}

void print_vector(const std::vector<integer>& vec) {
    if (vec.empty())
        return;
    auto i = vec.begin();
    std::cout << *i++;
    for (; i != vec.end(); ++i)
        std::cout << ", " << *i;
    std::cout << '\n';
}

int main() {
    std::map<integer, std::pair<bool, integer>> cache;
    std::vector<integer> seeds, related, palindromes;
    for (integer n = 1; n <= 10000; ++n) {
        std::pair<bool, integer> p(true, n);
        std::vector<integer> seen;
        integer rev = reverse(n);
        integer sum = n;
        for (int i = 0; i < 500; ++i) {
            sum += rev;
            rev = reverse(sum);
            if (rev == sum) {
                p.first = false;
                p.second = 0;
                break;
            }
            auto iter = cache.find(sum);
            if (iter != cache.end()) {
                p = iter->second;
                break;
            }
            seen.push_back(sum);
        }
        for (integer s : seen)
            cache.emplace(s, p);
        if (!p.first)
            continue;
        if (p.second == n)
            seeds.push_back(n);
        else
            related.push_back(n);
        if (n == reverse(n))
            palindromes.push_back(n);
    }
    std::cout << "number of seeds: " << seeds.size() << '\n';
    std::cout << "seeds: ";
    print_vector(seeds);
    std::cout << "number of related: " << related.size() << '\n';
    std::cout << "palindromes: ";
    print_vector(palindromes);
    return 0;
}




Java: import java.math.BigInteger;
import java.util.*;

public class Lychrel {

    static Map<BigInteger, Tuple> cache = new HashMap<>();

    static class Tuple {
        final Boolean flag;
        final BigInteger bi;

        Tuple(boolean f, BigInteger b) {
            flag = f;
            bi = b;
        }
    }

    static BigInteger rev(BigInteger bi) {
        String s = new StringBuilder(bi.toString()).reverse().toString();
        return new BigInteger(s);
    }

    static Tuple lychrel(BigInteger n) {
        Tuple res;
        if ((res = cache.get(n)) != null)
            return res;

        BigInteger r = rev(n);
        res = new Tuple(true, n);
        List<BigInteger> seen = new ArrayList<>();

        for (int i = 0; i < 500; i++) {
            n = n.add(r);
            r = rev(n);

            if (n.equals(r)) {
                res = new Tuple(false, BigInteger.ZERO);
                break;
            }

            if (cache.containsKey(n)) {
                res = cache.get(n);
                break;
            }

            seen.add(n);
        }

        for (BigInteger bi : seen)
            cache.put(bi, res);

        return res;
    }

    public static void main(String[] args) {

        List<BigInteger> seeds = new ArrayList<>();
        List<BigInteger> related = new ArrayList<>();
        List<BigInteger> palin = new ArrayList<>();

        for (int i = 1; i <= 10_000; i++) {
            BigInteger n = BigInteger.valueOf(i);

            Tuple t = lychrel(n);

            if (!t.flag)
                continue;

            if (n.equals(t.bi))
                seeds.add(t.bi);
            else
                related.add(t.bi);

            if (n.equals(t.bi))
                palin.add(t.bi);
        }

        System.out.printf("%d Lychrel seeds: %s%n", seeds.size(), seeds);
        System.out.printf("%d Lychrel related%n", related.size());
        System.out.printf("%d Lychrel palindromes: %s%n", palin.size(), palin);
    }
}