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;
}



Go: package main

import (
	"flag"
	"fmt"
	"math"
	"math/big"
	"os"
)

var maxRev = big.NewInt(math.MaxUint64 / 10) 
var ten = big.NewInt(10)




func reverseInt(v *big.Int, result *big.Int) *big.Int {
	if v.Cmp(maxRev) <= 0 {
		
		result.SetUint64(reverseUint64(v.Uint64()))
	} else {
		if true {
			
			s := reverseString(v.String())
			result.SetString(s, 10)
		} else {
			
			
			v := new(big.Int).Set(v)
			digit := new(big.Int)
			result.SetUint64(0)
			for v.BitLen() > 0 {
				v.QuoRem(v, ten, digit)
				result.Mul(result, ten)
				result.Add(result, digit)
			}
		}
	}
	return result
}

func reverseUint64(v uint64) uint64 {
	var r uint64
	for v > 0 {
		r *= 10
		r += v % 10
		v /= 10
	}
	return r
}

func reverseString(s string) string {
	b := make([]byte, len(s))
	for i, j := 0, len(s)-1; j >= 0; i, j = i+1, j-1 {
		b[i] = s[j]
	}
	return string(b)
}

var known = make(map[string]bool)

func Lychrel(n uint64, iter uint) (isLychrel, isSeed bool) {
	v, r := new(big.Int).SetUint64(n), new(big.Int)
	reverseInt(v, r)
	seen := make(map[string]bool)
	isLychrel = true
	isSeed = true
	for i := iter; i > 0; i-- {
		str := v.String()
		if seen[str] {
			
			isLychrel = true
			break
		}
		if ans, ok := known[str]; ok {
			
			isLychrel = ans
			isSeed = false
			break
		}
		seen[str] = true

		v = v.Add(v, r)
		
		reverseInt(v, r)
		if v.Cmp(r) == 0 {
			
			isLychrel = false
			isSeed = false
			break
		}
	}
	for k := range seen {
		known[k] = isLychrel
	}
	
	return isLychrel, isSeed
}

func main() {
	max := flag.Uint64("max", 10000, "search in the range 1..`N` inclusive")
	iter := flag.Uint("iter", 500, "limit palindrome search to `N` iterations")
	flag.Parse()
	if flag.NArg() != 0 {
		flag.Usage()
		os.Exit(2)
	}

	fmt.Printf("Calculating using n = 1..%v and %v iterations:\n", *max, *iter)
	var seeds []uint64
	var related int
	var pals []uint64
	for i := uint64(1); i <= *max; i++ {
		if l, s := Lychrel(i, *iter); l {
			if s {
				seeds = append(seeds, i)
			} else {
				related++
			}
			if i == reverseUint64(i) {
				pals = append(pals, i)
			}
		}
	}

	fmt.Println("      Number of Lychrel seeds:", len(seeds))
	fmt.Println("                Lychrel seeds:", seeds)
	fmt.Println("            Number of related:", related)
	fmt.Println("Number of Lychrel palindromes:", len(pals))
	fmt.Println("          Lychrel palindromes:", pals)
}